Android 使用DialogFragment 实现一个可以多选的Dialog

来源:互联网 发布:mysql fetch array 编辑:程序博客网 时间:2024/06/05 14:49

 

   DialogFragment 是官方推荐使用的,它既能实现传统Dialog的效果(dialog 和 AlertDialog),又能管理好自己的生命周期,横竖屏切换时也能保存原来的状态。


 下面一步一步来实现一个带多选框的Dialog,如下图展示



1,实现Dialog的布局

 dialog_layout :

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.dhl.dialogsamples.MainActivity">    <android.support.v7.widget.RecyclerView        android:id="@+id/recycler_view"        android:layout_width="match_parent"        android:layout_height="300dp"        android:padding="5dp"        >    </android.support.v7.widget.RecyclerView>        <TextView        android:id="@+id/sure_action"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="确定"        android:layout_alignParentRight="true"        android:layout_below="@id/recycler_view"        android:background="@drawable/qmui_s_list_item_bg_with_border_none"        android:textColor="@color/dialog_action_text_color"        android:padding="10dp"        android:layout_marginBottom="10dp"        android:layout_margin="5dp"        android:textSize="14sp"        />    <TextView        android:id="@+id/cancel_action"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="取消"        android:layout_below="@id/recycler_view"        android:layout_toLeftOf="@id/sure_action"        android:background="@drawable/qmui_s_list_item_bg_with_border_none"        android:textColor="@color/dialog_action_text_color"        android:padding="10dp"        android:layout_marginBottom="10dp"        android:layout_margin="5dp"        android:textSize="14sp"        /></RelativeLayout>

一个RecyclerView 实现多选布局,高度限制300dp ,下面置上 取消 和 确定 两个按钮。


dialog_item 布局:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="50dp"    android:gravity="center"    android:background="@drawable/qmui_s_list_item_bg_with_border_none"    android:clickable="true"    android:focusable="true"    tools:context="com.dhl.dialogsamples.MainActivity">    <TextView        android:id="@+id/text_check"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentLeft="true"        android:layout_centerVertical="true"        android:gravity="center"        android:text="选项"        android:layout_marginLeft="10dp"        />    <ImageView        android:id="@+id/image_check"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentRight="true"        android:layout_marginRight="10dp"        android:layout_centerVertical="true"        android:background="@drawable/qmui_s_checkbox"        /></RelativeLayout>

这个布局包括一个TextView 和ImageView ,ImageView 实现是否选中的效果。这里要注意下

 android:background="@drawable/qmui_s_list_item_bg_with_border_none"

这里适配了5.0以上水波纹的效果,5.0 以下普通触发效果

drawable 目录下 5.0- 的效果:

<?xml version="1.0" encoding="utf-8"?><!-- 单选类型的对话框的单选Drawable --><selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:drawable="@drawable/qmui_icon_checkbox_checked" android:state_selected="true"></item>    <item android:drawable="@drawable/qmui_icon_checkbox_checked" android:state_checked="true"></item>    <item android:drawable="@drawable/qmui_icon_checkbox_normal"></item></selector>
drawable-v21 目录下5.0+的效果:

<?xml version="1.0" encoding="utf-8"?><ripple xmlns:android="http://schemas.android.com/apk/res/android"        android:color="@color/qmui_drawable_color_list_pressed">    <item android:drawable="@color/qmui_config_color_white"/></ripple>


2,代码实现

DialogFragment :

public class MutiChoiceDialog extends DialogFragment {    private RecyclerView recyclerView ;    private TextView sure_action ,cancel_action;    /**     * 记录是否被选中     */    private SparseArray<Boolean> sparseArray ;    private List<Integer> listPosition ;    /**     * 回调给界面     */    interface OnSureListener    {        void onSureClick(List<Integer> list);    }    private OnSureListener onSureListener ;    public void setOnSureListener(OnSureListener onSureListener) {        this.onSureListener = onSureListener;    }    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //setCancelable(false);        //setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme_Holo_Light_Dialog_MinWidth);    }    @Override    public View onCreateView(LayoutInflater inflater,  ViewGroup container, Bundle savedInstanceState) {       View view = inflater.inflate(R.layout.dialog_layout,container,false) ;        Log.e("MutiChoiceDialog","===onCreateView");        initId(view);       /* Window dialogWindow = getDialog().getWindow();        WindowManager.LayoutParams lp = dialogWindow.getAttributes();        dialogWindow.setGravity(Gravity.CENTER );        lp.x = 0;        lp.y = 0;        lp.width = lp.MATCH_PARENT;        lp.height = 500;        lp.alpha = 0.7f;        dialogWindow.setAttributes(lp);*/        return view ;    }    private void initId(View view)    {        sparseArray = new SparseArray();        listPosition = new ArrayList<>();        recyclerView = (RecyclerView)view.findViewById(R.id.recycler_view);        sure_action = (TextView) view.findViewById(R.id.sure_action) ;        cancel_action = (TextView)view.findViewById(R.id.cancel_action);        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));        final MutiChoiceAdapter mutiChoiceAdapter = new MutiChoiceAdapter(getContext());        recyclerView.setAdapter(mutiChoiceAdapter);        mutiChoiceAdapter.setOnItemClikListener(new MutiChoiceAdapter.OnItemClikListener() {            @Override            public void onItemClick(MutiChoiceAdapter.MyViewHolder viewHolder, int position) {                if(sparseArray.get(position)!=null) {                    if(sparseArray.get(position))                    {                        listPosition.remove(position);                    }else                    {                        listPosition.add(position);                    }                    sparseArray.put(position, !sparseArray.get(position));                    viewHolder.imageView.setSelected(sparseArray.get(position));                   // viewHolder.itemView.findViewById(R.id.image_check).setSelected(sparseArray.get(position));                }else                {                    sparseArray.put(position, true);                    viewHolder.imageView.setSelected(true);                    listPosition.add(position);                }                mutiChoiceAdapter.setSparseArray(sparseArray);               // mutiChoiceAdapter.notifyDataSetChanged();            }        });        sure_action.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {          if(onSureListener != null)          {              onSureListener.onSureClick(listPosition);          }             dismiss();            }        });        cancel_action.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                dismiss();            }        });        //sure_btn.setEnabled(false);    }    /**     * 横竖屏切换适配     * @param newConfig     */    @Override    public void onConfigurationChanged(Configuration newConfig) {        super.onConfigurationChanged(newConfig);        Log.e("MutiChoiceDialog","===onConfigurationChanged");        if(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)        {            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)recyclerView.getLayoutParams();            layoutParams.height = Utils.dp2px(getContext(),200);            recyclerView.setLayoutParams(layoutParams);        }else if(newConfig.orientation == Configuration.ORIENTATION_PORTRAIT)        {            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)recyclerView.getLayoutParams();            layoutParams.height = Utils.dp2px(getContext(),300);            recyclerView.setLayoutParams(layoutParams);        }    }}

RecyclerView 对应的Adapter:

public   class MutiChoiceAdapter extends RecyclerView.Adapter<MutiChoiceAdapter.MyViewHolder> {    interface OnItemClikListener    {        void onItemClick(MyViewHolder viewHolder, int position);    }    private OnItemClikListener onItemClikListener ;    private SparseArray<Boolean> sparseArray ;    public void setSparseArray(SparseArray sparseArray) {        this.sparseArray = sparseArray;    }    public void setOnItemClikListener(OnItemClikListener onItemClikListener) {        this.onItemClikListener = onItemClikListener;    }    private Context context ;    public MutiChoiceAdapter(Context context)    {        this.context = context ;        sparseArray = new SparseArray<>();    }    public  class  MyViewHolder extends RecyclerView.ViewHolder    {        public TextView text_check ;        public ImageView imageView ;        public MyViewHolder(View itemView)        {            super(itemView);            text_check = (TextView) itemView.findViewById(R.id.text_check);            imageView = (ImageView)itemView.findViewById(R.id.image_check);        }    }    @Override    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.dialog_item,parent,false));    }    @Override    public void onBindViewHolder(final MyViewHolder holder, final int position) {        final  int pos = holder.getLayoutPosition();        holder.text_check.setText("选项"+position);        if(sparseArray.get(pos)!=null) {            holder.imageView.setSelected(sparseArray.get(pos));        }else{            holder.imageView.setSelected(false);        }        holder.itemView.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                if(onItemClikListener != null)                {                    onItemClikListener.onItemClick(holder,pos);                }            }        });    }    @Override    public int getItemCount() {        return 15;    }}

在Activity里调用的代码:

 private void showDialog()    {       // FragmentManager fragmentManager =  getSupportFragmentManager();        MutiChoiceDialog mutiChoiceDialog = new MutiChoiceDialog();        mutiChoiceDialog.setOnSureListener(this);        mutiChoiceDialog.show(getSupportFragmentManager(),"");    }


这样一个DialogFragment就实现了。

最后附上MainActivity 的布局文件和code

activity_main:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.dhl.dialogsamples.MainActivity">    <Button        android:id="@+id/btn"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="多选Dialog"        /></RelativeLayout>

code :

public class MainActivity extends AppCompatActivity implements MutiChoiceDialog.OnSureListener {    private Button button ;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        button = (Button)findViewById(R.id.btn);        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                showDialog();            }        });    }    private void showDialog()    {       // FragmentManager fragmentManager =  getSupportFragmentManager();        MutiChoiceDialog mutiChoiceDialog = new MutiChoiceDialog();        mutiChoiceDialog.setOnSureListener(this);        mutiChoiceDialog.show(getSupportFragmentManager(),"");    }    @Override    public void onConfigurationChanged(Configuration newConfig) {        super.onConfigurationChanged(newConfig);    }    @Override    public void onSureClick(List<Integer> list) {       StringBuffer selectPosition = new StringBuffer();        for(Integer postion :list)        {            selectPosition.append(postion+",");        }        Toast.makeText(this,selectPosition.toString(),Toast.LENGTH_LONG).show();    }}

源码:Android 使用DialogFragment 实现一个可以多选的Dialog