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

 

   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


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值