7 files added
10 files modified
| | |
| | | implementation 'com.squareup.okhttp3:okhttp:4.9.0' |
| | | implementation 'com.squareup.retrofit2:retrofit:2.9.0' |
| | | implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0' //RXjava和retrofit结合 |
| | | implementation 'com.permissionx.guolindev:permissionx:1.2.2' //权限依赖让你推广你就发群里?没有别的群了? |
| | | implementation 'com.guolindev.permissionx:permissionx:1.6.0' //权限依赖 |
| | | implementation 'com.github.bumptech.glide:glide:4.12.0' |
| | | annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0' |
| | | implementation 'com.pangle.cn:ads-sdk-pro:4.0.2.2'//字节跳动 穿山甲广告 |
| | |
| | | package com.runt.open.mvvm; |
| | | |
| | | import android.os.Bundle; |
| | | import android.Manifest; |
| | | |
| | | import com.google.android.material.bottomnavigation.BottomNavigationView; |
| | | |
| | | import androidx.appcompat.app.AppCompatActivity; |
| | | import androidx.navigation.NavController; |
| | | import androidx.navigation.Navigation; |
| | | import androidx.navigation.ui.AppBarConfiguration; |
| | | import androidx.navigation.ui.NavigationUI; |
| | | |
| | | import com.permissionx.guolindev.PermissionX; |
| | | import com.runt.open.mvvm.base.activities.BaseActivity; |
| | | import com.runt.open.mvvm.data.PhoneDevice; |
| | | import com.runt.open.mvvm.databinding.ActivityMainBinding; |
| | | import com.runt.open.mvvm.listener.ResPonse; |
| | | import com.runt.open.mvvm.ui.main.MainViewModel; |
| | | |
| | | public class MainActivity extends AppCompatActivity { |
| | | |
| | | private ActivityMainBinding binding; |
| | | public class MainActivity extends BaseActivity<ActivityMainBinding, MainViewModel> { |
| | | |
| | | @Override |
| | | protected void onCreate(Bundle savedInstanceState) { |
| | | super.onCreate(savedInstanceState); |
| | | |
| | | binding = ActivityMainBinding.inflate(getLayoutInflater()); |
| | | setContentView(binding.getRoot()); |
| | | |
| | | public void initViews() { |
| | | NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_activity_main); |
| | | NavigationUI.setupWithNavController(binding.navView, navController); |
| | | checkPermission(); |
| | | } |
| | | |
| | | private void showPermissionDialog(){ |
| | | |
| | | showDialog("警告", "软件需要权限才能运行", "申请权限", "退出", new ResPonse() { |
| | | @Override |
| | | public void doSuccess(Object obj) { |
| | | checkPermission(); |
| | | } |
| | | |
| | | @Override |
| | | public void doError(Object obj) { |
| | | finish(); |
| | | System.exit(0); |
| | | } |
| | | }); |
| | | } |
| | | private void checkPermission(){ |
| | | PermissionX.init(MainActivity.this) |
| | | .permissions(Manifest.permission.READ_PHONE_STATE) |
| | | .request((allGranted, grantedList, deniedList) -> { |
| | | if(allGranted){ |
| | | PhoneDevice.setDevice(mContext); |
| | | }else{ |
| | | showPermissionDialog(); |
| | | } |
| | | |
| | | }); |
| | | } |
| | | } |
| | |
| | | import android.view.WindowManager; |
| | | import android.view.inputmethod.InputMethodManager; |
| | | import android.widget.EditText; |
| | | import android.widget.TextView; |
| | | import android.widget.Toast; |
| | | |
| | | import androidx.annotation.ColorRes; |
| | |
| | | import com.runt.open.mvvm.R; |
| | | import com.runt.open.mvvm.base.model.BaseViewModel; |
| | | import com.runt.open.mvvm.base.model.ViewModelFactory; |
| | | import com.runt.open.mvvm.listener.ResPonse; |
| | | |
| | | import java.io.File; |
| | | import java.lang.reflect.Method; |
| | |
| | | } |
| | | |
| | | |
| | | AlertDialog dialog; |
| | | /** |
| | | * 显示弹框 |
| | | * @param title |
| | | * @param msg |
| | | * @param btnOk |
| | | * @param btnCancel |
| | | * @param resPonse |
| | | */ |
| | | public void showDialog(String title, String msg, String btnOk,String btnCancel,final ResPonse resPonse){ |
| | | showDialog(title,msg,null,btnOk,btnCancel,resPonse,false); |
| | | } |
| | | |
| | | private void showDialog(String title, String msg, String hint,String btnOk,String btnCancel,final ResPonse resPonse,boolean isEdit){ |
| | | |
| | | AlertDialog.Builder builder = new AlertDialog.Builder(this,R.style.TransparentDialog); |
| | | builder.setCancelable(false); |
| | | final View view = LayoutInflater.from(this).inflate(R.layout.layout_dialog,null); |
| | | TextView titleView = view.findViewById(R.id.txt_title); |
| | | TextView cancelView = view.findViewById(R.id.txt_cancel); |
| | | final TextView textView = view.findViewById(R.id.msg); |
| | | if(isEdit){ |
| | | textView.setEnabled(true); |
| | | }else{ |
| | | textView.setBackground(null); |
| | | } |
| | | cancelView.setOnClickListener(new View.OnClickListener() { |
| | | @Override |
| | | public void onClick(View v) { |
| | | dialog.dismiss(); |
| | | if(resPonse !=null){ |
| | | resPonse.doError(null); |
| | | } |
| | | } |
| | | }); |
| | | cancelView.setText(btnCancel); |
| | | TextView confirmView = view.findViewById(R.id.txt_confirm); |
| | | confirmView.setOnClickListener(new View.OnClickListener() { |
| | | @Override |
| | | public void onClick(View v) { |
| | | dialog.dismiss(); |
| | | if(resPonse !=null){ |
| | | resPonse.doSuccess(textView.getText().toString()); |
| | | } |
| | | } |
| | | }); |
| | | confirmView.setText(btnOk); |
| | | confirmView.requestFocus(); |
| | | if(hint != null){ |
| | | textView.setHint(hint); |
| | | } |
| | | if(msg != null){ |
| | | textView.setText(msg); |
| | | } |
| | | titleView.setText(title); |
| | | builder.setView(view); |
| | | dialog = builder.create(); |
| | | dialog.show(); |
| | | } |
| | | |
| | | AlertDialog loadingDialog; |
| | | /** |
| | | * 显示加载弹框 |
| | |
| | | getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); |
| | | //透明导航栏 |
| | | getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); |
| | | |
| | | setStatusBarTextColor(isBlack); |
| | | } |
| | | |
| | | /** |
| | |
| | | smartRefresh.finishLoadMore(); |
| | | } |
| | | } |
| | | |
| | | public A getAdapter() { |
| | | return adapter; |
| | | } |
| | |
| | | package com.runt.open.mvvm.base.model; |
| | | |
| | | import androidx.lifecycle.MutableLiveData; |
| | | import androidx.lifecycle.ViewModel; |
| | | |
| | | import com.runt.open.mvvm.retrofit.observable.HttpObserver; |
| | | import com.runt.open.mvvm.data.LoadingCmd; |
| | | import com.runt.open.mvvm.retrofit.AndroidScheduler; |
| | | import com.runt.open.mvvm.retrofit.observable.HttpObserver; |
| | | |
| | | import io.reactivex.Observable; |
| | | import io.reactivex.schedulers.Schedulers; |
| | |
| | | */ |
| | | public class BaseViewModel extends ViewModel { |
| | | |
| | | MutableLiveData<LoadingCmd> loadLive = new MutableLiveData<>(); |
| | | |
| | | public MutableLiveData<LoadingCmd> getLoadLive() { |
| | | return loadLive; |
| | | } |
| | | |
| | | /** |
| | | * 网络请求观察 |
| | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 网络请求观察 |
| | | * @param observable |
| | | * @param <T> |
| | | * @return |
| | | */ |
| | | public <T> void httpObserverOnLoading(Observable<T> observable, HttpObserver observer){ |
| | | observable.subscribeOn(Schedulers.io())//指定网络请求在io后台线程中进行 |
| | | .doOnSubscribe(disposable -> { |
| | | loadLive.setValue(new LoadingCmd(LoadingCmd.CMD.LOADING,"请求数据中...")); |
| | | }) |
| | | .observeOn(AndroidScheduler.mainThread()) |
| | | .doOnComplete(() -> { |
| | | loadLive.postValue(new LoadingCmd(LoadingCmd.CMD.DISSMISS)); |
| | | }) |
| | | .subscribe(observer); |
| | | } |
| | | |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.runt.open.mvvm.data; |
| | | |
| | | /** |
| | | * My father is Object, ites purpose of |
| | | * |
| | | * @purpose Created by Runt (qingingrunt2010@qq.com) on 2022/1/28. |
| | | */ |
| | | public class LoadingCmd { |
| | | public CMD code;public String msg; |
| | | |
| | | public LoadingCmd(CMD code) { |
| | | this(code,""); |
| | | } |
| | | |
| | | public LoadingCmd(CMD code, String msg) { |
| | | this.code = code; |
| | | this.msg = msg; |
| | | } |
| | | |
| | | public enum CMD{LOADING,DISSMISS} |
| | | } |
New file |
| | |
| | | package com.runt.open.mvvm.data; |
| | | |
| | | import android.content.Context; |
| | | import android.os.Build; |
| | | |
| | | import com.runt.open.mvvm.util.DeviceUtil; |
| | | import com.runt.open.mvvm.util.NetWorkUtils; |
| | | |
| | | /** |
| | | * My father is Object, ites purpose of |
| | | * |
| | | * @purpose Created by Runt (qingingrunt2010@qq.com) on 2020-10-7. |
| | | */ |
| | | |
| | | public class PhoneDevice { |
| | | |
| | | private String brand,model,androidVersion,androidCode,seriaNo,netIp; |
| | | |
| | | static PhoneDevice device; |
| | | |
| | | public static void setDevice(Context context) { |
| | | device = new PhoneDevice(Build.BRAND,Build.MODEL,Build.VERSION.SDK_INT+"",Build.VERSION.RELEASE, DeviceUtil.getSerialNumber(context), NetWorkUtils.getNetIp()); |
| | | } |
| | | |
| | | public static PhoneDevice getDevice() { |
| | | return device; |
| | | } |
| | | |
| | | public PhoneDevice(String brand, String model, String androidVersion, String androidCode, String seriaNo, String netIp) { |
| | | this.brand = brand; |
| | | this.model = model; |
| | | this.androidVersion = androidVersion; |
| | | this.androidCode = androidCode; |
| | | this.seriaNo = seriaNo; |
| | | this.netIp = netIp; |
| | | } |
| | | |
| | | public String getBrand() { |
| | | return brand; |
| | | } |
| | | |
| | | public void setBrand(String brand) { |
| | | this.brand = brand; |
| | | } |
| | | |
| | | public String getModel() { |
| | | return model; |
| | | } |
| | | |
| | | public void setModel(String model) { |
| | | this.model = model; |
| | | } |
| | | |
| | | public String getAndroidVersion() { |
| | | return androidVersion; |
| | | } |
| | | |
| | | public void setAndroidVersion(String androidVersion) { |
| | | this.androidVersion = androidVersion; |
| | | } |
| | | |
| | | public String getAndroidCode() { |
| | | return androidCode; |
| | | } |
| | | |
| | | public void setAndroidCode(String androidCode) { |
| | | this.androidCode = androidCode; |
| | | } |
| | | |
| | | public String getSeriaNo() { |
| | | return seriaNo; |
| | | } |
| | | |
| | | public void setSeriaNo(String seriaNo) { |
| | | this.seriaNo = seriaNo; |
| | | } |
| | | |
| | | public String getNetIp() { |
| | | return netIp; |
| | | } |
| | | |
| | | public void setNetIp(String netIp) { |
| | | this.netIp = netIp; |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public String toString() { |
| | | return "PhoneDevice{" + |
| | | "brand='" + brand + '\'' + |
| | | ", model='" + model + '\'' + |
| | | ", androidVersion='" + androidVersion + '\'' + |
| | | ", androidCode='" + androidCode + '\'' + |
| | | ", seriaNo='" + seriaNo + '\'' + |
| | | ", netIp='" + netIp + '\'' + |
| | | '}'; |
| | | } |
| | | } |
New file |
| | |
| | | package com.runt.open.mvvm.listener; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * Created by Administrator on 2018/5/25. |
| | | */ |
| | | public abstract class ResPonse<T> implements Serializable { |
| | | |
| | | public abstract void doSuccess(T obj); |
| | | |
| | | public void doError(T obj){}; |
| | | |
| | | } |
| | |
| | | |
| | | import android.util.Log; |
| | | |
| | | import androidx.annotation.NonNull; |
| | | import androidx.lifecycle.MutableLiveData; |
| | | |
| | | |
| | | import com.runt.open.mvvm.data.BaseApiResult; |
| | | |
| | | import java.io.IOException; |
| | | import java.lang.reflect.ParameterizedType; |
| | | import java.net.SocketTimeoutException; |
| | | |
| | | import io.reactivex.SingleObserver; |
| | | import io.reactivex.observers.DisposableObserver; |
| | | import retrofit2.Response; |
| | | |
| | | /** |
| | | * 网络请求观察 |
| | | * Created by Administrator on 2021/11/11 0011. |
| | | */ |
| | | public abstract class HttpObserver<T extends BaseApiResult> extends DisposableObserver<T>{ |
| | | public abstract class HttpObserver<M extends BaseApiResult> extends DisposableObserver<Response<M>> implements SingleObserver<Response<M>> { |
| | | |
| | | final String TAG = "HttpObserver"; |
| | | |
| | | MutableLiveData<T> resultLive; |
| | | MutableLiveData<M> resultLive; |
| | | |
| | | public HttpObserver(MutableLiveData<T> resultLive) { |
| | | public HttpObserver(MutableLiveData<M> resultLive) { |
| | | this.resultLive = resultLive; |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public void onNext(T value) { |
| | | resultLive.setValue(value); |
| | | public void onNext(Response<M> response) { |
| | | onExcuted(response); |
| | | } |
| | | |
| | | @Override |
| | |
| | | |
| | | try { |
| | | Log.e(TAG,this.getClass().getSimpleName()+" "+throwable.getMessage()); |
| | | Class<T> entityClass = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]; |
| | | T t = entityClass.newInstance();//实例化一个泛型 |
| | | Class<M> entityClass = (Class<M>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]; |
| | | M t = entityClass.newInstance();//实例化一个泛型 |
| | | t.code = 410; |
| | | if( throwable instanceof SocketTimeoutException){ |
| | | t.msg = "服务请求超时,请稍候再试";//设置错误信息 |
| | |
| | | resultLive.setValue(t); |
| | | } catch (ClassCastException e) { |
| | | e.printStackTrace(); |
| | | T t = (T) new BaseApiResult<String>(); |
| | | M t = (M) new BaseApiResult<String>(); |
| | | t.code = 409; |
| | | t.msg = "实例化对象未指定泛型实体类"; |
| | | resultLive.setValue(t); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | T t = (T) new BaseApiResult<String>(); |
| | | M t = (M) new BaseApiResult<String>(); |
| | | t.code = 409; |
| | | t.msg = e.getMessage(); |
| | | resultLive.setValue(t); |
| | |
| | | } |
| | | |
| | | @Override |
| | | public void onSuccess(Response<M> response) { |
| | | onExcuted(response); |
| | | } |
| | | |
| | | private void onExcuted(@NonNull Response<M> response){ |
| | | |
| | | if(response.body() != null){ |
| | | resultLive.setValue(response.body()); |
| | | }else{ |
| | | try { |
| | | String error = response.errorBody().string(); |
| | | Log.i("subscribe","onExcuted "+error); |
| | | onError(new Throwable(error)); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | | @Override |
| | | public void onComplete() { |
| | | Log.i("subscribe","onComplete"); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.runt.open.mvvm.ui.main; |
| | | |
| | | import com.runt.open.mvvm.base.model.BaseViewModel; |
| | | |
| | | /** |
| | | * My father is Object, ites purpose of |
| | | * |
| | | * @purpose Created by Runt (qingingrunt2010@qq.com) on 2022/1/28. |
| | | */ |
| | | public class MainViewModel extends BaseViewModel { |
| | | } |
| | |
| | | import android.view.View; |
| | | import android.view.ViewGroup; |
| | | import android.widget.TextView; |
| | | |
| | | import androidx.annotation.NonNull; |
| | | import androidx.annotation.Nullable; |
| | | import androidx.fragment.app.Fragment; |
| | |
| | | public class DashboardFragment extends Fragment { |
| | | |
| | | private DashboardViewModel dashboardViewModel; |
| | | private FragmentDashboardBinding binding; |
| | | private FragmentDashboardBinding binding; |
| | | |
| | | public View onCreateView(@NonNull LayoutInflater inflater, |
| | | ViewGroup container, Bundle savedInstanceState) { |
| | | ViewGroup container, Bundle savedInstanceState) { |
| | | dashboardViewModel = |
| | | new ViewModelProvider(this).get(DashboardViewModel.class); |
| | | |
| | | binding = FragmentDashboardBinding.inflate(inflater, container, false); |
| | | View root = binding.getRoot(); |
| | | binding = FragmentDashboardBinding.inflate(inflater, container, false); |
| | | View root = binding.getRoot(); |
| | | |
| | | final TextView textView = binding.textDashboard; |
| | | dashboardViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() { |
| | |
| | | return root; |
| | | } |
| | | |
| | | @Override |
| | | @Override |
| | | public void onDestroyView() { |
| | | super.onDestroyView(); |
| | | binding = null; |
| | |
| | | import android.view.View; |
| | | import android.view.ViewGroup; |
| | | import android.widget.TextView; |
| | | |
| | | import androidx.annotation.NonNull; |
| | | import androidx.annotation.Nullable; |
| | | import androidx.fragment.app.Fragment; |
| | | import androidx.lifecycle.Observer; |
| | | import androidx.lifecycle.ViewModelProvider; |
| | | |
| | | import com.runt.open.mvvm.base.fragments.BaseFragment; |
| | | import com.runt.open.mvvm.databinding.FragmentHomeBinding; |
| | | |
| | | public class HomeFragment extends Fragment { |
| | | public class HomeFragment extends BaseFragment<FragmentHomeBinding,HomeViewModel> { |
| | | |
| | | private HomeViewModel homeViewModel; |
| | | private FragmentHomeBinding binding; |
| | | |
| | | public View onCreateView(@NonNull LayoutInflater inflater, |
| | | ViewGroup container, Bundle savedInstanceState) { |
| | | homeViewModel = |
| | | new ViewModelProvider(this).get(HomeViewModel.class); |
| | | |
| | | binding = FragmentHomeBinding.inflate(inflater, container, false); |
| | | View root = binding.getRoot(); |
| | | |
| | | @Override |
| | | public void initViews() { |
| | | final TextView textView = binding.textHome; |
| | | homeViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() { |
| | | viewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() { |
| | | @Override |
| | | public void onChanged(@Nullable String s) { |
| | | textView.setText(s); |
| | | } |
| | | }); |
| | | return root; |
| | | } |
| | | |
| | | @Override |
| | | public void onDestroyView() { |
| | | super.onDestroyView(); |
| | | binding = null; |
| | | } |
| | | } |
| | |
| | | import android.view.View; |
| | | import android.view.ViewGroup; |
| | | import android.widget.TextView; |
| | | |
| | | import androidx.annotation.NonNull; |
| | | import androidx.annotation.Nullable; |
| | | import androidx.fragment.app.Fragment; |
| | |
| | | public class NotificationsFragment extends Fragment { |
| | | |
| | | private NotificationsViewModel notificationsViewModel; |
| | | private FragmentNotificationsBinding binding; |
| | | private FragmentNotificationsBinding binding; |
| | | |
| | | public View onCreateView(@NonNull LayoutInflater inflater, |
| | | ViewGroup container, Bundle savedInstanceState) { |
| | | ViewGroup container, Bundle savedInstanceState) { |
| | | notificationsViewModel = |
| | | new ViewModelProvider(this).get(NotificationsViewModel.class); |
| | | |
| | | binding = FragmentNotificationsBinding.inflate(inflater, container, false); |
| | | View root = binding.getRoot(); |
| | | binding = FragmentNotificationsBinding.inflate(inflater, container, false); |
| | | View root = binding.getRoot(); |
| | | |
| | | final TextView textView = binding.textNotifications; |
| | | notificationsViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() { |
| | |
| | | return root; |
| | | } |
| | | |
| | | @Override |
| | | @Override |
| | | public void onDestroyView() { |
| | | super.onDestroyView(); |
| | | binding = null; |
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <selector xmlns:android="http://schemas.android.com/apk/res/android" > |
| | | |
| | | <item android:state_enabled="false" android:color="@color/enable_txt_color"/> <!-- pressed --> |
| | | |
| | | <item android:state_pressed="true" android:color="@color/white"/> <!-- pressed --> |
| | | |
| | | <item android:state_focused="true" android:color="@color/white"/> <!-- focused --> |
| | | |
| | | <item android:color="@color/txt_color"/> <!-- default --> |
| | | |
| | | </selector> |
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <ripple xmlns:android="http://schemas.android.com/apk/res/android" |
| | | android:color="@color/color_gray" > |
| | | <item> |
| | | <selector xmlns:android="http://schemas.android.com/apk/res/android"> |
| | | <item android:state_enabled="false"> |
| | | <shape> |
| | | <solid android:color="@color/transparent" /> |
| | | </shape> |
| | | </item> |
| | | <item android:state_focused="true"> |
| | | <shape> |
| | | <solid android:color="@color/white" /> |
| | | <stroke android:width="0.5dp" android:color="@color/txt_normal" /> |
| | | <corners android:radius="@dimen/edit_corner" /> |
| | | </shape> |
| | | </item> |
| | | <item> |
| | | <shape> |
| | | <solid android:color="@color/white" /> |
| | | <stroke android:width="0.5dp" android:color="@color/gray_normal" /> |
| | | <corners android:radius="@dimen/edit_corner" /> |
| | | </shape> |
| | | </item> |
| | | </selector> |
| | | </item> |
| | | |
| | | </ripple> |
| | |
| | | xmlns:app="http://schemas.android.com/apk/res-auto" |
| | | android:id="@+id/container" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="match_parent" |
| | | android:paddingTop="?attr/actionBarSize" > |
| | | android:layout_height="match_parent" > |
| | | |
| | | <com.runt.open.mvvm.widgets.TitleBarView |
| | | android:id="@+id/title_bar" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="?attr/actionBarSize" |
| | | android:background="@color/white" |
| | | app:layout_constraintTop_toTopOf="parent" |
| | | app:layout_constraintLeft_toLeftOf="parent" |
| | | app:layout_constraintRight_toRightOf="parent" /> |
| | | |
| | | <com.google.android.material.bottomnavigation.BottomNavigationView |
| | | android:id="@+id/nav_view" |
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="wrap_content" |
| | | android:background="@drawable/bg_white_corner_8" |
| | | android:orientation="vertical"> |
| | | |
| | | <TextView |
| | | android:id="@+id/txt_title" |
| | | android:gravity="center" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="wrap_content" |
| | | android:padding="20dp" |
| | | android:text="标题" |
| | | android:textSize="18sp" |
| | | android:textColor="@color/black" /> |
| | | |
| | | <View |
| | | android:layout_width="match_parent" |
| | | android:layout_height="0.5dp" |
| | | android:background="@color/black_20" /> |
| | | |
| | | <EditText |
| | | android:id="@+id/msg" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="wrap_content" |
| | | android:padding="10dp" |
| | | android:layout_margin="30dp" |
| | | android:background="@drawable/edit_dialog_bg_white_border" |
| | | android:enabled="false" |
| | | android:textColor="@color/txt_normal" |
| | | android:text="" /> |
| | | |
| | | |
| | | <View |
| | | android:layout_width="match_parent" |
| | | android:layout_height="0.5dp" |
| | | android:background="@color/black_20" /> |
| | | <LinearLayout |
| | | android:layout_width="match_parent" |
| | | android:layout_height="wrap_content" |
| | | android:orientation="horizontal"> |
| | | |
| | | <TextView |
| | | android:id="@+id/txt_cancel" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="wrap_content" |
| | | android:padding="20dp" |
| | | android:layout_weight="1" |
| | | android:gravity="center" |
| | | android:text="取消" |
| | | android:textSize="14sp" |
| | | android:focusable="true" |
| | | android:textColor="@color/text_normal" |
| | | android:background="@drawable/btn_white_lb_corner" /> |
| | | |
| | | <View |
| | | android:layout_width="0.5dp" |
| | | android:layout_height="match_parent" |
| | | android:background="@color/black_20" /> |
| | | <TextView |
| | | android:id="@+id/txt_confirm" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="wrap_content" |
| | | android:padding="20dp" |
| | | android:focusable="true" |
| | | android:layout_weight="1" |
| | | android:gravity="center" |
| | | android:textSize="14sp" |
| | | android:text="确认" |
| | | android:textColor="@color/text_normal" |
| | | android:background="@drawable/btn_white_rb_corner" /> |
| | | |
| | | |
| | | </LinearLayout> |
| | | |
| | | |
| | | </LinearLayout> |