【问题标题】:Customize dialog which has single-choice list items自定义具有单选列表项的对话框
【发布时间】:2012-03-23 12:42:19
【问题描述】:

我创建了一个带有单选列表项的对话框

final CharSequence[] items = {"Red", "Green", "Blue"};

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Colors");
builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int item) {
                Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();
            }
        });
AlertDialog alert = builder.create();
alert.show();

如何自定义此对话框的布局,以便对话框中的每个列表项都包含一个图标和一个文本。如何为对话框上的列表创建自定义布局?

【问题讨论】:

    标签: android android-alertdialog


    【解决方案1】:

    创建自定义对话框的步骤:

    1. 创建对话框布局文件,如:

      <RelativeLayout xmlns:android = "http://schemas.android.com/apk/res/android"
      android:layout_width = "wrap_content"
      android:layout_height = "wrap_content">
      <!-- The Title Bar -->
      <LinearLayout
          android:id="@+id/dlg_priority_titlebar"
          android:orientation="horizontal"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:layout_alignParentTop="true">
      
          <ImageView
              android:src="@drawable/image"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_margin="5dip" />
      
          <TextView
              android:layout_width = "wrap_content"
                  android:layout_height = "wrap_content"
                  android:text = "Select Task Priority"
                  android:layout_gravity = "center_vertical" />
      </LinearLayout>
      <ListView 
          android:id="@+id/dlg_priority_lvw"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_below="@+id/dlg_priority_titlebar"
          android:background="@drawable/layout_home_bg">
      </ListView>
      

    2. 因为布局在ListView自定义,所以要为ListView创建布局文件:

      <LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android" 
          android:orientation = "horizontal" 
          android:layout_width = "fill_parent" 
          android:layout_height = "fill_parent"> 
      
      <ImageView 
            android:id = "@+id/list_priority_img" 
            android:layout_width = "wrap_content" 
            android:layout_height = "wrap_content" 
            android:layout_gravity = "center_vertical" 
            android:layout_margin = "5dip" /> 
      <TextView 
           android:id = "@+id/list_priority_value" 
           android:layout_width = "wrap_content" 
           android:layout_height = "wrap_content" 
           android:layout_gravity = "center_vertical" 
           android:textsize = "28dip" 
           android:textColor = "@drawable/ black" /> 
      </LinearLayout>
      
    3. 创建一个继承自Dialog的自定义DialogPriorityDlg

           public class PriorityDlg extends Dialog {
      
          private Context context;
          private ListView dlg_priority_lvw = null;
          public PriorityDlg(Context context) {
              super(context);
              this.context = context;
              // TODO Auto-generated constructor stub
          }
          public PriorityDlg(Context context, int theme) {
              super(context, theme);
              this.context = context;
          }
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              // TODO Auto-generated method stub
              super.onCreate(savedInstanceState);
              this.setContentView(R.layout.dlg_priority);
              dlg_priority_lvw = (ListView) findViewById(R.id.dlg_priority_lvw);
              // ListView
              SimpleAdapter adapter = new SimpleAdapter(context, getPriorityList(),
                      R.layout.lvw_priority, new String[] { "list_priority_img",
                              "list_priority_value" }, new int[] {
                              R.id.list_priority_img, R.id.list_priority_value });
              dlg_priority_lvw.setAdapter(adapter);
              //ListView
              dlg_priority_lvw
                      .setOnItemClickListener(new AdapterView.OnItemClickListener() {
      
                          @Override
                          public void onItemClick(AdapterView<?> arg0, View arg1,
                                  int arg2, long arg3) {
      
                          }
                      });
          }
          private List<HashMap<String, Object>> getPriorityList() {
              List<HashMap<String, Object>> priorityList = new ArrayList<HashMap<String, Object>>();
              HashMap<String, Object> map1 = new HashMap<String, Object>();
              map1.put("list_priority_img", R.drawable.priority_not_important);
              map1.put("list_priority_value", context.getResources().getString(
                      R.string.dlg_priority_not_important));
              priorityList.add(map1);
              HashMap<String, Object> map2 = new HashMap<String, Object>();
              map2.put("list_priority_img", R.drawable.priority_general);
              map2.put("list_priority_value", context.getResources().getString(
                      R.string.dlg_priority_general));
              priorityList.add(map2);
              HashMap<String, Object> map3 = new HashMap<String, Object>();
              map3.put("list_priority_img", R.drawable.priority_important);
              map3.put("list_priority_value", context.getResources().getString(
                      R.string.dlg_priority_important));
              priorityList.add(map3);
              HashMap<String, Object> map4 = new HashMap<String, Object>();
              map4.put("list_priority_img", R.drawable.priority_very_important);
              map4.put("list_priority_value", context.getResources().getString(
                      R.string.dlg_priority_very_important));
              priorityList.add(map4);
      
              return priorityList;
          }
      
      }
      
    4. 创建自定义对话框

      PriorityDlg dlg = new PriorityDlg (SimpleTaskActivity.this, R.style.dlg_priority); 
      dlg.show();
      

    其中R.style.dlg_priority设置对话框使用的样式文件,只是让对话框去掉标题栏,当然你也可以通过代码来完成这个效果:

    <? Xml version = "1.0" encoding = "utf-8"?> 
    <resources> 
        <style name="dlg_priority" parent="@android:Theme.Dialog"> 
            <item name = "android: windowNoTitle"> true </ item> 
        </ style> 
    </ resources>
    

    【讨论】:

    • 这个周末我会试试你的代码,然后告诉你,谢谢
    【解决方案2】:

    您基本上必须通过以下方式创建自己的ListAdapter 子类化可用的适配器类之一并将其提供给 对话框(使用builder.setAdapter(...))。如果你有一个数组或 项目/对象列表,子类化ArrayAdapter 可能是什么 你会想要调查的。

    在您的 Adapter 子类中,您覆盖 getView(...) 方法(以及其他方法)并用数据填充自定义布局的视图 对于列表中提供的位置。更具体地说,你会想要 针对ImageView 设置图像并将文本设置为TextView

     Create class `MySimpleArrayAdapter` extending from  `ArrayAdapter`. 
    

    使用ListView.setOnItemClickListener() 方法我们得到CheckTextView 的选定值

    #dialog.xml
    <?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"
        android:background="@color/whitebox_bg"
        android:orientation="horizontal" >
    
            <CheckedTextView
                android:id="@+id/textDialog"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:checkMark="?android:attr/listChoiceIndicatorSingle"
                android:gravity="center_vertical"
                android:maxLines="10"
                android:singleLine="false"
                android:text=""
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:textColor="#000000" />
    
    </LinearLayout>
    

    创建自定义对话框

            String [] view_location = {"Red", "Green", "Blue"};
                  TextView label = (TextView) findViewById(R.id.selected_dept);
                  AlertDialog.Builder builder = new AlertDialog.Builder(this);
                  builder.setTitle("Select Location");
                  ListView listview = new ListView(this);
                  listview.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
                          LayoutParams.WRAP_CONTENT));
                  listview.setCacheColorHint(0);
                  listview.setBackgroundColor(Color.WHITE);
    
    
                  if (view_location != null) {
    
                      MySimpleArrayAdapter choice_arrayAdapter = new MySimpleArrayAdapter(this, view_location,label.getText().toString());
                      listview.setAdapter(choice_arrayAdapter);
                      builder.setView(listview);
    
                      listview.setOnItemClickListener(new OnItemClickListener() {
                          @Override
                          public void onItemClick(AdapterView<?> arg0, View arg1,
                                  int arg2, long arg3) {
                              // TODO Auto-generated method stub
                              TextView label = (TextView) findViewById(R.id.selected_dept);
                              label.setText(view_location[arg2]);
                              survedObjectId = view_location_id[arg2];
                              dInterface.dismiss();
    
                          }
                      });
    
    
                  }
                  Dialog dialog = builder.create();
                  dInterface = dialog;
                  dialog.getWindow().setLayout(200, 400);
                  dialog.show();'
    
        // `Extends From ArrayAdapter
    
         'public class MySimpleArrayAdapter extends ArrayAdapter<String> {
                 private final Context context;
                 private final String[] values;
                 private final String  selectedText;
                 public MySimpleArrayAdapter(Context context, String[] values, String  selectedText) {
                   super(context, R.layout.dialog_text, values);
                   this.context = context;
                   this.values = values;
                   this.selectedText = selectedText;
                 }
    
                 @Override
                 public View getView(int position, View convertView, ViewGroup parent) {
                   LayoutInflater inflater = (LayoutInflater) context
                       .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                   View rowView = inflater.inflate(R.layout.dialog_text, parent, false);
                   CheckedTextView textView = (CheckedTextView) rowView.findViewById(R.id.textDialog);
    
                   textView.setText(values[position]);
                   if(textView.getText().toString().equals(selectedText))
                   {
                     textView.setChecked(true);
                   }
                   else
                   {
                     textView.setChecked(false);
                   }
    
                   return rowView;
                 }
               }'
    

    【讨论】:

      【解决方案3】:

      您基本上必须通过子类化可用的适配器类之一来创建自己的 ListAdapter 并将其提供给对话框(使用builder.setAdapter(...))。如果您有一个数组或项目/对象列表,则可能需要对 ArrayAdapter 进行子类化。

      在您的 Adapter 子类中,您覆盖 getView(...) 方法(以及其他方法)并使用列表中提供的位置的数据填充自定义布局的视图。更具体地说,您需要针对 ImageView 设置图像并将文本设置为 TextView。

      可以在here 找到一个相当不错的教程,该教程演示了如何实现自定义 ArrayAdapter,并且恰好接近您想要完成的任务。它还展示了如何使用 ViewHolder/RowWrapper 概念。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-07
        • 2011-07-12
        • 1970-01-01
        相关资源
        最近更新 更多