当列表中存在不同的布局时,从列表项中检索值

时间:2013-08-08 12:24:52

标签: android

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

我的listview由多个布局组成,因此我无法确定在调用onItemClick方法时正在按哪个布局。例如,listview中布局中的一个项目是:

// 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}&lt;&lt;&lt;我不能对这个字符串做任何事情,除非我尝试使用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();
    }
}

2 个答案:

答案 0 :(得分:1)

这是一种简单的方法 - 将其粘贴到每个xml视图中:

android:onClick="someFunction"

然后在someFunction内执行:

public void someFunction(View v){

switch (v.getId()){
case R.id.lblSub:
  // This layout was clicked, do something about it
  break;

case R.id.lblMain:
  // This layout was clicked, do something about it
  break;

}

答案 1 :(得分:1)

我的理解是你有3种类型的物品:

  • 部分标题(由于areAllItemsSelectableisEnabled方法而被停用,因此无法点击)
  • 单品
  • 双项目

您还有2个部分,姓名和电话。

第1部分(adapter.getItemViewType(position) == 1)中的项目是单个项目,而第2部分(adapter.getItemViewType(position) == 2)。

在这两种情况下,您的item对象(adapter.getItem(position))都被声明为Map<String, ?>,甚至被定义为Map<String, String>

这意味着您可以将项目投放到Map

Map<String, String> itemAsMap = (Map<String, String>) item;

然后使用ITEM_VALUEITEM_CAPTION键从地图中获取您的值。