0

我有一个包含不同 xml 布局的列表视图,每个布局都有不同的视图。我想知道如何在方法内部从用户单击的项目内部的视图中获取数据onItemClick

我的列表视图由多个布局组成,因此我无法确定调用 onItemClick 方法时按下的是哪个布局。例如,列表视图中布局中的一项是:

// list_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

    <TextView
        android:id="@+id/lblSub"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:padding="6dp"
        android:layout_marginRight="4dp"
        android:text=""
        android:textColor="#FFFFFF"
        android:textSize="18sp" />

    <TextView
        android:id="@+id/lblMain"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:padding="6dp"
        android:layout_marginLeft="4dp"
        android:text=""
        android:textColor="#FFFFFF"
        android:textSize="18sp" />

</RelativeLayout>

列表视图中的另一个布局可能是:

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

    <TextView
        android:id="@+id/lblName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="4dp"
        android:padding="4dp"
        android:text="TextView"
        android:textColor="#FFFFFF"
        android:textSize="28sp" />

</RelativeLayout>

所以我不知道如何为列表视图中的任何布局获取所有这些视图的数据。

我之前的尝试是这样的:

public void onItemClick(AdapterView<?> listView, View view, int position, long id) {            
    Object obj = adapter.getItem(position);
    String value = obj.toString();
}

但是在这种情况下,返回一个包含该项目内所有视图的所有值的字符串value,例如:可能是用户创建的。{caption=MobileNumber, value=07000123456}substring

这是我正在使用的适配器(感谢Jeff Sharkey,我没有创建此适配器):

public class SeparatedListAdapter extends BaseAdapter {  

    public final Map<String,Adapter> sections = new LinkedHashMap<String,Adapter>();  
    public final ArrayAdapter<String> headers;  
    public final static int TYPE_SECTION_HEADER = 0;  

    public SeparatedListAdapter(Context context) {  
        headers = new ArrayAdapter<String>(context, R.layout.list_header);  
    }  

    public void addSection(String section, Adapter adapter) {  
        this.headers.add(section);  
        this.sections.put(section, adapter);  
    }
    public void addSectionNoHeader(String section, Adapter adapter) {
        this.sections.put(section, adapter);
    }

    public Object getItem(int position) {  
        for(Object section : this.sections.keySet()) {  
            Adapter adapter = sections.get(section);  
            int size = adapter.getCount() + 1;  

            // check if position inside this section   
            if(position == 0) return section;  
            if(position < size) return adapter.getItem(position - 1);  

            // otherwise jump into next section  
            position -= size;  
        }  
        return null;  
    }  

    public int getCount() {  
        // total together all sections, plus one for each section header  
        int total = 0;  
        for(Adapter adapter : this.sections.values())  
            total += adapter.getCount() + 1;  
        return total;  
    }  

    public int getViewTypeCount() {  
        // assume that headers count as one, then total all sections  
        int total = 1;  
        for(Adapter adapter : this.sections.values())  
            total += adapter.getViewTypeCount();  
        return total;  
    }  

    public int getItemViewType(int position) {  
        int type = 1;  
        for(Object section : this.sections.keySet()) {  
            Adapter adapter = sections.get(section);  
            int size = adapter.getCount() + 1;  

            // check if position inside this section   
            if(position == 0) return TYPE_SECTION_HEADER;  
            if(position < size) return type + adapter.getItemViewType(position - 1);  

            // otherwise jump into next section  
            position -= size;  
            type += adapter.getViewTypeCount();  
        }  
        return -1;  
    }  

    public boolean areAllItemsSelectable() {  
        return false;  
    }  

    public boolean isEnabled(int position) {  
        return (getItemViewType(position) != TYPE_SECTION_HEADER);  
    }  

    @Override  
    public View getView(int position, View convertView, ViewGroup parent) {  
        int sectionnum = 0;  
        for(Object section : this.sections.keySet()) {  
            Adapter adapter = sections.get(section);  
            int size = adapter.getCount() + 1;  

            // check if position inside this section   
            if(position == 0) return headers.getView(sectionnum, convertView, parent);  
            if(position < size) return adapter.getView(position - 1, convertView, parent);  

            // otherwise jump into next section  
            position -= size;  
            sectionnum++;  
        }  
        return null;  
    }  

    @Override  
    public long getItemId(int position) {  
        return position;  
    }  

}  

我正在寻找一种方法来提取项目内所有视图的值。但是,已单击的项目可能是任何布局之一这一事实让我感到困惑。有任何想法吗?

编辑:

这是我如何在代码中使用此适配器的示例:

SeparatedListAdapter adapter;
Customer cust;
ListView lvDetails;

public Map<String,?> createDoubleItem(String title, String caption) {  
        Map<String,String> item = new HashMap<String,String>();  
        item.put(ITEM_VALUE, title);  
        item.put(ITEM_CAPTION, caption);  
        return item;  
    }

    public Map<String,?> createSingleItem(String name) {  
        Map<String,String> item = new HashMap<String,String>();  
        item.put(ITEM_VALUE, name);
        return item;
    } 

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

        Intent intent = getIntent();
        cust = Db.Functions.getCustomer(intent.getStringExtra("uuid"));
        lvDetails = (ListView) findViewById(R.id.custdetails);
        adapter = new SeparatedListAdapter(this);
        lvDetails.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> listView, View view, int position, long id) {
                Gen.popup("Item clicked");
            }
        });

        // Name
        List<Map<String,?>> name = new LinkedList<Map<String,?>>();
        if (cust.firstName == null && cust.lastName == null)
            name.add(createSingleItem("Unnamed Customer"));
        else
            name.add(createSingleItem(
                    ((cust.title != null) ? cust.title + " " : "") +
                    ((cust.firstName != null) ? cust.firstName + " " : "") +
                    ((cust.lastName != null) ? cust.lastName : "")));
        adapter.addSection("Name", new SimpleAdapter(this, name, R.layout.list_item_name,   
                new String[] { ITEM_VALUE },
                new int[] { R.id.lblName }));
        // Phones
        if ((cust.mobileNumber != null || cust.homeNumber != null || cust.workNumber != null) && SHOW_PHONES)
        {
            List<Map<String,?>> phone = new LinkedList<Map<String,?>>();
            if (cust.mobileNumber != null)
                phone.add(createDoubleItem(cust.mobileNumber, "Mobile"));
            if (cust.homeNumber != null)
                phone.add(createDoubleItem(cust.homeNumber, "Home"));
            if (cust.workNumber != null)
                phone.add(createDoubleItem(cust.workNumber, "Work"));
            adapter.addSection("Phone", new SimpleAdapter(this, phone, R.layout.list_item,   
                    new String[] { ITEM_VALUE, ITEM_CAPTION },
                    new int[] { R.id.lblSub, R.id.lblMain }));
        }  
        lvDetails.setAdapter(adapter);
        adapter.notifyDataSetChanged();
    }
}
4

1 回答 1

2

首先,您为该适配器提供的链接看起来很旧(2008 年,5 年前)我会看一个像这样的 3rd 方库

但这不是重点。

适配器的设计非常复杂,因为其中有多个适配器,所以如果不启动我自己的测试项目,我无法确定这将如何工作。

现在,当您调用 onItemClick 时,您要添加以下内容

int viewType = adapter.getItemViewType(position);
if (viewType == SeparatedListAdapter.TYPE_SECTION_HEADER) {
    //header clicked handle that here maybe do nothing
} else {
    Map<String,?> clickedItem = (Map<String,?>) adapter.getItem(position);
    String value = (String) clickedItem.Get(ITEM_VALUE);
    String caption = (String) clickedItem.Get(ITEM_CAPTION);
    //here you can do things with the clicked item
    //also because you know the view type you can find other views on it
}

编辑:根据您提供的内容调整了 onclick 的外观

于 2013-08-07T16:02:54.973 回答