自定义带有setMultiChoiceItems的对话框

11

我想创建一个用户可以像下面的图像一样选择选项的方式

在此输入图像描述

目前我正在进行以下操作

public static class CategoriesDialogFragment extends SherlockDialogFragment {

    public static CategoriesDialogFragment newInstance(int title) {
        CategoriesDialogFragment frag = new CategoriesDialogFragment();
        Bundle args = new Bundle();
        args.putInt("title", title);
        frag.setArguments(args);
        return frag;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        int title = getArguments().getInt("title");

        return new AlertDialog.Builder(getActivity())
                .setIcon(R.drawable.alert_dialog_icon)
                .setTitle(title)
                .setMultiChoiceItems(_categories, _selections,
                        new DialogSelectionClickHandler())
                .setPositiveButton(R.string.alert_dialog_ok,
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                    int whichButton) {
                                ((MainActivity) getActivity())
                                        .doPositiveClick();
                            }
                        }).create();

        /*
         * .setNegativeButton(R.string.alert_dialog_cancel, new
         * DialogInterface.OnClickListener() { public void
         * onClick(DialogInterface dialog, int whichButton) {
         * ((MainActivity) getActivity()) .doNegativeClick(); } })
         */
    }

    public class DialogSelectionClickHandler implements
            DialogInterface.OnMultiChoiceClickListener {
        public void onClick(DialogInterface dialog, int clicked,
                boolean selected) {
            // Log.i("ME", _options[clicked] + " selected: " + selected);
        }
    }

}

但是我想要像图片中那样添加“全部”选项。所以我认为我需要构建一个自定义对话框。是否仍然可以扩展原生的setMultiChoiceItems方法,以减少我的代码处理量。


Builder类有一个setCustomTitle(View)方法。 - user
@Luksprog 需要有一个复选框,就像图片中所示。这样当我点击它时,我想要检查或取消选择对话框内容中的所有内容。 - Harsha M V
我们将为该方法提供一个视图,其中包含一个TextView(实际标题)和all CheckBox - user
@Luksprog 哦,好的。你能分享一些相关资源吗?我想看看如何完成它。我认为我们需要构建一个自定义对话框。 - Harsha M V
3个回答

9

您可能可以使用 AlertDialog.Builder 类的 setCustomTitle() 方法,并构建自己的标题,其中包括标题文本和所有 CheckBox,例如:

new AlertDialog.Builder(getActivity())
                .setIcon(R.drawable.alert_dialog_icon)
                .setTitle(title)
                .setCustomTitle(getLayoutInflater().inflate(R.layout.custom_title, null));

其中R.layout.custom_title的含义是:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <TextView
        android:id="@+id/textView1"
        style="?android:attr/textAppearanceLarge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Dialog title"
        android:textColor="#ffffff" />

    <TextView
        android:id="@+id/all"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="All"
        android:textColor="#ffffff" />

    <CheckBox
        android:id="@+id/checkBox1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

还需要进行其他样式调整,使其看起来更好。但是,考虑到整个对话框布局,您可能希望使用自定义Dialog类,该类不会提供setMultiChoice()方法(但最终很容易复制)。


类型 DialogFragment 中的方法 getLayoutInflater(Bundle) 对于参数 () 不适用。 - Harsha M V
@HarshaMV getActivity().getLayoutInflater() - user
我已经完成了上述操作并实现了自定义标题,但是如何从对象中获取值呢?findViewById 不起作用 :/ - Alex Fragotsis
1
@AlexanderFragotsis 扩展定制标题,并存储对其的引用并从那里修改它。 View title = getLayoutInflater().inflate(R.layout.custom_title, null); ....setCustomTitle(title); title.findViewById(etc) - user

2
我已经实现了你在图片中展示的东西。我使用的是自定义对话框,就像你想要使用的那样。我在xml文件中使用了Listview。
首先,初始化以下arraylist。
// Catagory Selection
    public static ArrayList<String> acceptpositionwhoesNearMe = new ArrayList<String>();
    public static String AcceptCatagotyIDWhoesNearMe = "";

以下是我使用的showDialog()代码。
public void showDialog() {
        Log.i(TAG, "Inside Show Dialog");
        final Dialog warning = new Dialog(logout_dialogue.this);
        warning.requestWindowFeature(Window.FEATURE_NO_TITLE);
        warning.setContentView(R.layout.YOUR_XML);
        warning.setCancelable(false);
        warning.getWindow().setGravity(Gravity.CENTER);

        WindowManager mWinMgr;
        mWinMgr = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
        int displayWidth = mWinMgr.getDefaultDisplay().getWidth();

        warning.getWindow().setLayout(displayWidth - 75,
                LayoutParams.WRAP_CONTENT);
        warning.setOnDismissListener(new OnDismissListener() {
            public void onDismiss(DialogInterface dialog) {
                Log.i(TAG, "Inside Dialog interface");
                // test = true;
                warning.dismiss();
            }
        });
        ListView listinterest = (ListView) warning
                .findViewById(R.id.list_catagory);
        /*
         * ArrayList<String> count = new ArrayList<String>(); count.clear();
         * count.add("Hotels"); count.add("Restaurants"); count.add("Gardens");
         * count.add("Theater");
         */
        CatagorySummaryAdapter adapter;
        adapter = new CatagorySummaryAdapter(YOUR_ACTIVITY.this,
                YOUR_ARRAYLIST_OF_CATAGORY, true);

        listinterest.setAdapter(adapter);

        Button btnOk = (Button) warning.findViewById(R.id.btn_close);
        btnOk.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                // TODO Auto-generated method stub

                String Catagory = "";
                int count = HomeActivity.acceptpositionwhoesNearMe.size();

                if (count > 0) {
                    for (int i = 0; i < HomeActivity.acceptpositionwhoesNearMe
                            .size(); i++) {

                        int pos = Integer
                                .parseInt(HomeActivity.acceptpositionwhoesNearMe
                                        .get(i));
                        if (Catagory.equals("")) {
                            Catagory = GetUserDetailsJsonParser.CategoryName
                                    .get(pos);
                            HomeActivity.AcceptCatagotyIDWhoesNearMe = GetUserDetailsJsonParser.CategoryID
                                    .get(pos);
                        } else {

                            Catagory = Catagory
                                    + ","
                                    + GetUserDetailsJsonParser.CategoryName
                                            .get(pos);
                            HomeActivity.AcceptCatagotyIDWhoesNearMe = HomeActivity.AcceptCatagotyIDWhoesNearMe
                                    + ","
                                    + GetUserDetailsJsonParser.CategoryID
                                            .get(pos);
                        }

                    }

                    Log.i(TAG, "Accept Catagory IDs WhoseNear Me"
                            + HomeActivity.AcceptCatagotyIDWhoesNearMe);

                    GetUserDetailsJsonParser.InterestedIn = HomeActivity.AcceptCatagotyIDWhoesNearMe;
                    UpdateMap = true;
                    /*
                     * startActivity(new Intent(WhosNearMe.this,
                     * BuildInukshk_4.class));
                     */
                    new GetUsersInRadiusAsyncTask().execute();

                    warning.dismiss();

                } else {
                    Toast.makeText(WhosNearMe.this,
                            "Please Select One or More Catagory", 3).show();
                }
                // test = true;

            }
        });

        warning.show();
    }

这里是我的logout_dialogue.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/edittext_back_final"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" >

            <com.inukshk.CustomTextViewBold
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:layout_marginTop="10dp"
                android:text="Interested in"
                android:textColor="#3C3C3C"
                android:textSize="18sp"
                android:textStyle="bold" />
        </LinearLayout>

        <ListView
            android:id="@+id/list_catagory"
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:layout_weight="1"
            android:cacheColorHint="#00000000"
            android:divider="@android:color/transparent" >
        </ListView>

        <Button
            android:id="@+id/btn_close"
            android:layout_width="99dp"
            android:layout_height="40dp"
            android:layout_alignParentLeft="true"
            android:layout_marginLeft="10dp"
            android:background="@drawable/btn_back_final"
            android:text="CLOSE"
            android:textColor="#ffffff"
            android:textSize="16dp"
            android:textStyle="bold" />
    </LinearLayout>

</LinearLayout>

这里是我的CatagorySummaryAdapter.java

package com.inukshk.adapter;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.inukshk.HomeActivity;
import com.inukshk.R;
import com.inukshk.CreateInukshk.BuildInukshk_3;
import com.inukshk.WhosNearMe.WhosNearMe;

public class CatagorySummaryAdapter extends BaseAdapter {

    public Activity context;
    String TAG = "CatagorySummaryAdapter";
    public LayoutInflater inflater;
    public ArrayList<String> Count;
    boolean Dialogue;

    public CatagorySummaryAdapter(Activity context, ArrayList<String> Count,
            boolean Dialogue) {
        super();
        this.context = context;
        this.inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        this.Count = Count;

        this.Dialogue = Dialogue;

        // TODO Auto-generated constructor stub
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return Count.size();
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return Count.get(position);
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public int getItemViewType(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    public class ViewHolder {
        RelativeLayout lsummary_row;
        TextView txtinterestname;
        CheckBox chkinterest;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        int pos = position;
        ViewHolder holder;

        if (convertView == null) {
            holder = new ViewHolder();

            if (Dialogue) {
                convertView = inflater.inflate(
                        R.layout.listview_summary_dialogue_row, null);
            } else {
                convertView = inflater.inflate(R.layout.listview_summary_row,
                        null);
            }

            holder.txtinterestname = (TextView) convertView
                    .findViewById(R.id.txtinterestname);
            holder.lsummary_row = (RelativeLayout) convertView
                    .findViewById(R.id.lsummary_row);
            holder.chkinterest = (CheckBox) convertView
                    .findViewById(R.id.chkinterest);
            holder.chkinterest.setEnabled(true);

            holder.chkinterest.setTag(position);

            if (Dialogue) {

                for (int i = 0; i < HomeActivity.acceptpositionwhoesNearMe.size(); i++) {
                    int index = Integer
                            .parseInt(HomeActivity.acceptpositionwhoesNearMe
                                    .get(i));
                    // Log.i(TAG, "Inside for Loop of Accept Positions");
                    if (index == position) {
                        // Log.i(TAG, "Matched for index" + index);
                        holder.chkinterest.setChecked(true);
                        holder.chkinterest
                                .setButtonDrawable(R.drawable.checkbox_checked);
                    }

                }

            } else {
                for (int i = 0; i < BuildInukshk_3.acceptposition.size(); i++) {
                    int index = Integer.parseInt(BuildInukshk_3.acceptposition
                            .get(i));
                    // Log.i(TAG, "Inside for Loop of Accept Positions");
                    if (index == position) {
                        // Log.i(TAG, "Matched for index" + index);
                        holder.chkinterest.setChecked(true);
                        holder.chkinterest
                                .setButtonDrawable(R.drawable.checkbox_checked);
                    }

                }
            }

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.chkinterest
                .setOnCheckedChangeListener(new OnCheckedChangeListener() {

                    @Override
                    public void onCheckedChanged(CompoundButton buttonView,
                            boolean isChecked) {
                        // TODO Auto-generated method stub
                        // Log.i(TAG, "ISChecked is " + isChecked);
                        if (isChecked) {
                            // Log.i(TAG, "ISChecked is true");
                            buttonView
                                    .setButtonDrawable(R.drawable.checkbox_checked);
                            int position = Integer.parseInt(buttonView.getTag()
                                    .toString());
                            if (Dialogue) {
                                HomeActivity.acceptpositionwhoesNearMe.add(String
                                        .valueOf(position));

                                Log.i(TAG, "Accept ID of Dialogue"
                                        + HomeActivity.acceptpositionwhoesNearMe);
                            } else {
                                BuildInukshk_3.acceptposition.add(String
                                        .valueOf(position));

                                Log.i(TAG, "Accept ID"
                                        + BuildInukshk_3.acceptposition);
                            }

                        } else {
                            // Log.i(TAG, "ISChecked is false");
                            buttonView
                                    .setButtonDrawable(R.drawable.checkbox_unchecked);
                            int position = Integer.parseInt(buttonView.getTag()
                                    .toString());

                            if (Dialogue) {
                                if (HomeActivity.acceptpositionwhoesNearMe
                                        .contains(String.valueOf(position))) {
                                    // Log.i(TAG,
                                    // "Inside Already present position");
                                    HomeActivity.acceptpositionwhoesNearMe
                                            .remove(String.valueOf(position));
                                    Log.i(TAG,
                                            "Accept ID Dialogue***"
                                                    + HomeActivity.acceptpositionwhoesNearMe);
                                }
                            } else {
                                if (BuildInukshk_3.acceptposition
                                        .contains(String.valueOf(position))) {
                                    // Log.i(TAG,
                                    // "Inside Already present position");
                                    BuildInukshk_3.acceptposition.remove(String
                                            .valueOf(position));
                                    Log.i(TAG, "Accept ID ***"
                                            + BuildInukshk_3.acceptposition);
                                }
                            }
                            //
                        }

                    }
                });

        holder.txtinterestname.setText(Count.get(pos));

        return convertView;
    }

}

尝试阅读以下内容,可能会对您有所帮助。


使用DialogFragments时,不能使用setMultiChoiceItems吗? - Harsha M V
@HarshaMV:我还没有使用SherlockDialogFragment,所以无法给您正确的建议。非常抱歉。 - Bhavesh Patadiya
没有问题。你能分享一下如何实现全选和取消全选的代码吗?因为你提到过已经实现了这个功能,我认为我们可以很容易地将你的代码移植到DialogFragment中。 - Harsha M V
我已经编辑了我的回答,请看一下。如果您有任何困难,请告诉我。 - Bhavesh Patadiya

1

我也希望继续使用setMultiChoiceItems()来创建对话框,所以我没有创建自定义对话框,而是这样做:

不要立即返回AlertDialog。首先像这样创建AlertDialog.Builder

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

设置您的构建器参数:

builder.setTitle(listTitle)
.setMultiChoiceItems(allTagsArray, containsTag,
            new DialogInterface.OnMultiChoiceClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which, boolean isChecked){

然后创建AlertDialog本身,调用create()方法。这不会立即显示对话框。

AlertDialog dialog = builder.create();

接着获取ListView,添加一个头部和/或尾部,并返回它。

ListView dialogList = dialog.getListView();
dialogList.addFooterView(yourHeader);
return dialog;

这也适用于@Luksprog的setCustomTitle(),可以提供三个可定制空间,而无需实现自定义适配器。对于某些人来说,唯一可能的缺点是标题和页脚随列表滚动(如果列表比屏幕长,则只会出现问题)。
希望这可以帮到你。
重要更新: 不要在复选框列表中使用标题。它会导致AlertController.java错误计算哪个复选框被选中,使其无用。仍然可以使用页脚,在这种情况下非常有用,但在我的情况下不是,所以我正在构建一个自定义对话框。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接