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);
}
}
}
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