【问题标题】:how to add customised layout to Arrayadapter?如何将自定义布局添加到 Arrayadapter?
【发布时间】:2015-03-27 09:16:04
【问题描述】:

我正在尝试创建具有自定义布局的ListViewlistView 中的每个项目应如下面的item.xml 所示。

在代码中,我使用了

adapter = new ArrayAdapter<T>(getApplicationContext(), R.layout.listi_tems_layout, topicsList);

但它不起作用,因为ArrayAdapter&lt;T&gt; 的构造函数接受第二个参数为int 类似

android.R.layout.simple_list_item_1

,在我的例子中,它是自定义布局,即

R.layout.listi_tems_layout

我应该使用哪个适配器或如何解决这个问题。谢谢

物品

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="3">

<TextView 
    android:id="@+id/tvlist_topic"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"/>
<ImageView 
    android:id="@+id/ivList_delete"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:clickable="true"
    android:src="@drawable/delete_icon"
    android:contentDescription="icon to delete item from the Listview"
    android:layout_weight="1"/>
<CheckBox 
    android:id="@+id/cbList_hook"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:checked="false"
    android:layout_weight="1"/>

主布局

<RelativeLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
....
....
....

<ListView 
    android:id="@+id/lvEco_topics"
    android:layout_width="match_parent"
    android:layout_height="470dp"
    android:layout_below="@id/tvEco_topic"
    android:layout_marginTop="30dp"
    android:scrollbars="vertical"
    android:divider="@android:drawable/alert_light_frame"></ListView>
<Button 
    android:id="@+id/btEco_save"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@id/lvEco_topics"
    android:gravity="center"
    android:text="Save"/>

代码

public class MainActivity extends Activity {

private ArrayList<String> topicsList;
private ListAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_activity);

    topicsList = new ArrayList<String>();
    topicsList.add("topic1");
    topicsList.add("topic2");
    topicsList.add("topic3");
    topicsList.add("topic4");
    topicsList.add("topic5");
    topicsList.add("topic6");

    adapter = new ArrayAdapter<T>(getApplicationContext(), R.layout.listi_tems_layout, topicsList);

【问题讨论】:

  • 使用adapter = new ArrayAdapter&lt;T&gt;(getApplicationContext(), R.layout.listi_tems_layout, topicsList);有什么问题?
  • @ρяσѕρєяK 我遇到的问题是 2 构造函数未定义"
  • @MD 我尝试了你的建议,但我收到警告说 2Type 安全:构造函数 ArrayAdapter(Context, int, List) 属于原始类型 ArrayAdapter。对泛型类型 ArrayAdapter 的引用应该被参数化”
  • 将适配器创建为ArrayAdapter&lt;String&gt; adapter = new ArrayAdapter&lt;String&gt;(MainActivity.this, R.layout.listi_tems_layout, topicsList); 并查看我对其他更改的回答

标签: android android-layout listview android-arrayadapter


【解决方案1】:

我不确定它是否仍然相关, 从源 ArrayAdapter 似乎有在第三个参数中接受 textview 资源的构造函数,不确定它是否是 2017 年新添加的:D,

ArrayAdapter adapter = new ArrayAdapter<>(context,YourCustomLayoutID,TextViewIDinYourLayout,ListData);

从源头来看,如果您没有提供 textview 布局 id,它将假定整个视图是一个 textview,所以我认为可以在不扩展/创建新适配器的情况下使用自定义视图(我知道,我讨厌自己创建一个),但您需要提供用于文本的文本视图

【讨论】:

    【解决方案2】:

    创建一个类并像这样使用基本适配器进行扩展,然后设置此适配器

    import java.util.ArrayList;
    
    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.TextView;
    
    import com.example.test.R;
    import com.itoks.model.ClientDetails;
    
    public class ClientListAdapter extends BaseAdapter {
        // ArrayList<String> name, company, email, id, status;
        ArrayList<ClientDetails> clientArrayList;
        Context c;
    
        public ClientListAdapter(Context c, ArrayList<ClientDetails> list) {
            clientArrayList = list;
            this.c = c;
    
        }
    
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return clientArrayList.size();
        }
    
        @Override
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            return clientArrayList.get(position);
        }
    
        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return position;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            View row = null;
            LayoutInflater inflater = (LayoutInflater) c
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            if (convertView == null) {
                row = inflater.inflate(R.layout.listview_item_clients, parent,
                        false);
            } else {
                row = convertView;
            }
            ClientDetails detail = clientArrayList.get(position);
            TextView name = (TextView) row.findViewById(R.id.tvClientFullName);
            name.setText(detail.name);
            TextView email = (TextView) row.findViewById(R.id.tvClientEmail);
            email.setText(detail.email);
            TextView id = (TextView) row.findViewById(R.id.tvClientID);
            id.setText("ID : " + detail.id);
            TextView company = (TextView) row
                    .findViewById(R.id.tvClientCompanyName);
            company.setText(detail.company);
            TextView status = (TextView) row.findViewById(R.id.tvClientStatus);
            status.setText("Status:" + detail.status);
            return row;
        }
    
    }
    

    【讨论】:

    • getItem 返回 null ??
    • 无论您是否可以使用自定义的 ArrayList 和位置访问该项目。
    • 还是不好的做法。
    • return clientArrayList.get(position);当然......您还应该防止构造函数中的空列表
    • 但是在这个项目中我不需要直接访问那个项目。这就是为什么我在这里返回 null。
    【解决方案3】:

    请创建您自己的扩展 ArrayAdapter.

    的 ItemAdapter
    public class ItemAdapter extends ArrayAdapter<Item> {
    private int resource;
    private List<Item> items;
    
    public ItemAdapter(Context context, int resource, List<Item> items) {
        super(context, resource, items);
        this.resource = resource;
        this.items = items;
    }
    
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LinearLayout itemView;
        final Item item = getItem(position);
    
        if (convertView == null) {
            itemView = new LinearLayout(getContext());
    
            LayoutInflater layoutInflater = LayoutInflater.from(getContext());
            layoutInflater.inflate(resource, itemView, true);
        }
        else {
            itemView = (LinearLayout) convertView;
        }
    

    然后在 MainActivity onCreate() 中加载你的 item.xml

    public class MainActivity{
        private List<Item> items;
        private ItemAdapter itemAdapter;
        @Override
          protected void onCreate(Bundle savedInstanceState) {
          itemAdapter = new ItemAdapter(this, R.layout.item, items);
    

    【讨论】:

      【解决方案4】:

      据我了解。您正在尝试在 ArrayAdapter 中进行自定义布局。这是不可能的。您需要编写自己的自定义适配器扩展 arrayAdapter 类,您可以在其中定义如何使用您的主题列表处理自定义布局。像这样的:

      public class ChatUserAdapter extends ArrayAdapter<UserChat> {
      
      private Activity context;
      private List<UserChat> userList;
      private int ilayout;
      
      public ChatUserAdapter(Activity context, int layout, List<UserChat> userList) {
          super(context, layout, userList);
          this.context = context;
          this.userList = userList;
          this.ilayout = layout;
      }
      
      public long getItemId(int position) {
          return position;
      }
      
      static class ViewHolder {
          public TextView tvEmail;
      }
      
      @Override
      public View getView(int position, View convertView, ViewGroup parent) {
          ViewHolder viewHolder;
          View rowView = convertView;
          if (rowView == null) {
      
              LayoutInflater layoutInflater = context.getLayoutInflater();
              rowView = layoutInflater.inflate(ilayout, null, true);
              viewHolder = new ViewHolder();
              viewHolder.tvEmail = (TextView) rowView.findViewById(R.id.tv_email);
              rowView.setTag(viewHolder);
          } else {
              viewHolder = (ViewHolder) rowView.getTag();
          }
      
          UserChat item = userList.get(position);
          viewHolder.tvEmail.setText(item.getName() + " " + item.getSurname());
          return rowView;
      }
      }
      

      【讨论】:

      • 对于现场示例,请通过 youtube.com/watch?v=UMSdD05NVYQ
      • 将 Activity 传递给适配器是个坏主意,因为适配器会泄漏整个 Activity。
      【解决方案5】:

      ArrayAdapter 接受第二个参数为 int 之类的 android.R.layout.simple_list_item_1

      当不自定义ArrayAdaptergetView 方法时,自定义布局需要一个带有android:id="@android:id/text1" id 的TextView 并在一个TextView 中显示值。

      要使用当前代码运行应用程序,请在 R.layout.listi_tems_layout 布局中为 TextView 添加 android:id="@android:id/text1"

      因为R.layout.listi_tems_layout 布局还包含其他带有 TextView 的视图,所以通过扩展 ArrayAdapter 类来创建自定义适配器也可以访问其他视图。

      参见以下示例:Custom ArrayAdapter for a ListView (Android)

      【讨论】:

      • 好的,但是现在通过扩展“ArrayAdapter”,我需要指定参数“T”,ArrayAdapter,它应该是什么值?
      • @rmaik : 使用extends ArrayAdapter&lt;String&gt;
      • 是不是因为我拥有的 Arraylist 由字符串组成?
      • 其实id可以是任何你想要的。自定义布局的唯一要求是其中只有一个 TextView。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多