为 expandablelistview 的子级创建单独的 onClick() 方法

Posted

技术标签:

【中文标题】为 expandablelistview 的子级创建单独的 onClick() 方法【英文标题】:Make individual onClick() methods for children of expandablelistview 【发布时间】:2013-04-03 02:22:10 【问题描述】:

我有一个如下所示的可扩展列表视图。我已经做到了,当每个孩子被点击时,都会弹出一条祝酒消息。我需要每个孩子开始他们自己的活动/片段,这需要单独的 onClick() 方法。有人知道如何实现吗?谢谢。注意:我正在使用 SimonVT 的滑动菜单库,而且我对 android 编程还很陌生。

MainActivity.java:

package press.linx.expandablelistdemo;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.xml.sax.SAXException;

import net.simonvt.menudrawer.MenuDrawer;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.SimpleAdapter;
import android.widget.Toast;

public class MainActivity extends Activity 

ExpandableListView exv;
MenuDrawer mDrawer;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    mDrawer = MenuDrawer.attach(this);
    mDrawer.setContentView(R.layout.activity_main);
    mDrawer.setMenuView(R.layout.leftmenu);

    exv=(ExpandableListView)findViewById(R.id.expandableListView1);
    exv.setAdapter(new MyAdapter(this));

    exv.setOnChildClickListener(new OnChildClickListener() 

        @Override
        public boolean onChildClick(ExpandableListView parent, View v,
                int groupPosition, int childPosition, long id) 
            // TODO Auto-generated method stub
            String itemclicked = MyAdapter.childList[groupPosition][childPosition];
            Toast.makeText(getApplicationContext(), "you clicked " + itemclicked, Toast.LENGTH_SHORT).show();
            return false;
        

    );


private void setListAdapter(SimpleAdapter adapter) 
    // TODO Auto-generated method stub



@Override
public boolean onCreateOptionsMenu(Menu menu) 
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;



MyAdapter.java

package press.linx.expandablelistdemo;


import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;

public class MyAdapter extends BaseExpandableListAdapter 
private Context context;
Typeface typeface;
String []parentList = "Tech", "Best Of", "Art & Design", "Other";

static String [][] childList = 
        
            "All Tech", "Reviews", "Gaming", "Gadgets"
        ,
        
            "Android"
        ,
        
            "Architecture"
        ,
        
            "Infographics"
        
;
public MyAdapter(Context context) 
    // TODO Auto-generated constructor stub
    this.context=context;



@Override
public Object getChild(int arg0, int arg1) 
    // TODO Auto-generated method stub
    return null;


@Override
public long getChildId(int arg0, int arg1) 
    // TODO Auto-generated method stub
    return 0;


@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
        ViewGroup parent) 
    // TODO Auto-generated method stub
    //typeface = Typeface.createFromAsset(context.getAssets(), "font/robotochild.ttf"); 
    TextView tv = new TextView(context);
    tv.setText(childList[groupPosition][childPosition]);
    tv.setPadding(30, 10, 0, 10);
    tv.setTextSize(15);
    //tv.setTypeface(typeface); 
    tv.setTextColor(Color.WHITE);
    return tv;


@Override
public int getChildrenCount(int groupPosition) 
    // TODO Auto-generated method stub
    return childList[groupPosition].length;


@Override
public Object getGroup(int groupPosition) 
    // TODO Auto-generated method stub
    return groupPosition;


@Override
public int getGroupCount() 
    // TODO Auto-generated method stub
    return parentList.length;


@Override
public long getGroupId(int groupPosition) 
    // TODO Auto-generated method stub
    return groupPosition;


@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) 
    // TODO Auto-generated method stub
    TextView tv = new TextView(context);
    typeface = Typeface.createFromAsset(context.getAssets(), "font/roboto.ttf"); 
    tv.setText(parentList[groupPosition]);
    tv.setPadding(50, 10, 0, 10);
    tv.setTextSize(20);
    tv.setTextColor(Color.WHITE);
    tv.setTypeface(typeface); 
    return tv;


@Override
public boolean hasStableIds() 
    // TODO Auto-generated method stub
    return false;


@Override
public boolean isChildSelectable(int groupPosition, int childPosition) 
    // TODO Auto-generated method stub
    return true;



menulistview.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" 
android:background="@drawable/geowall">

<ExpandableListView
    android:id="@+id/expandableListView1"
    android:groupIndicator="@null"
    android:layout_
    android:layout_
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:padding="3dp" >
</ExpandableListView>

!

【问题讨论】:

【参考方案1】:

如果您希望每个按钮具有不同的功能,请考虑将它们存储为按钮的 tag 属性(在 XML 布局中)。 onChildClick 监听器中的View v 参数是被点击的孩子的View;然后可以使用它来检索标签,如下所示:

v.getTag();

您可以使用 switch-case 块来根据标记调用正确的活动,或者将活动的 exact 名称存储在标记中并通过反射将其传入以检索类为活动。或者,您可以存储一个 HashMap 将标记名称映射到 Activity 类/变量。

【讨论】:

【参考方案2】:

这可能是您正在寻找的。​​p>

让我们从在 Eclipse IDE 中创建一个项目开始吧。

    通过转到文件 ⇒ 新建 Android 项目来创建一个新项目。填写所有详细信息并将您的活动命名为 AndroidListViewActivity。 创建项目后,打开您的主要活动 java 文件(在本例中为 AndroidListViewActivity.java)并从 ListActivity 扩展类。

公共类 AndroidListViewActivity 扩展 ListActivity 3. 现在我们需要一个字符串资源文件来存储所有列表项标签。因此,在 values 文件夹下创建一个 XML 文件并将其命名为 list_data.xml 并粘贴以下代码。 (右键单击 res/values ⇒ 新建 ⇒ Android XML 文件)

list_data.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="adobe_products">
        <item>Adobe After Effects</item>
        <item>Adobe Bridge</item>
        <item>Adobe Dreamweaver</item>
        <item>Adobe Edge</item>
        <item>Adobe Fireworks</item>
        <item>Adobe Flash</item>
        <item>Adobe Photoshop</item>
        <item>Adobe Premiere</item>
        <item>Adobe Reader</item>
        <item>Adobe Illustrator</item>
    </string-array>
</resources>

    在 ListView 中,每个列表项都是一个 xml 布局,因此我们可以自定义每个列表项。在 res/layout 文件夹下创建一个 XML 文件并将其命名为 list_item.xml 并键入以下代码。此 xml 布局将是单个列表项行。 (右键单击 res/layout ⇒ 新建 ⇒ Android XML 文件)

    现在打开您的主要活动 java 文件 (AndroidListViewActivity.java) 并键入以下代码。在下面的代码中,我将导入所有 xml 资源数据并将它们存储在一个数组中。在下一步中,我将数组绑定到 ListAdapter。

AndroidListViewActivity.java

package com.androidhive.androidlistview;

import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class AndroidListViewActivity extends ListActivity 
    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

        // storing string resources into Array
        String[] adobe_products = getResources().getStringArray(R.array.adobe_products);

        // Binding resources Array to ListAdapter
        this.setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, R.id.label, adobe_products));

    

    现在运行您的项目,您可以看到带有数组项列表的列表视图。但是在单击单个列表项时,您看不到任何操作。所以我们需要开始选择单个列表项的新活动。

在选择单个列表项时启动新 Activity 在我之前的文章中,我已经解释了如何在屏幕之间切换。在这里,我将在新屏幕中显示单个列表项的详细信息。

    现在在 src 文件夹下创建新的活动类。右键单击 src/package 文件夹 ⇒ 新建 ⇒ 类并将其命名为 SingleListItem。 (SingleListItem.java) 打开您的 AndroidListViewActivity.java 并将代码修改为以下内容。在下面的代码中,我获取选定的列表项字符串(产品名称)并将其发送到新的 Activity。

AndroidListViewActivity.java

package com.androidhive.androidlistview;

import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class AndroidListViewActivity extends ListActivity 
    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

        // storing string resources into Array
        String[] adobe_products = getResources().getStringArray(R.array.adobe_products);

        // Binding resources Array to ListAdapter
        this.setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, R.id.label, adobe_products));

        ListView lv = getListView();

        // listening to single list item on click
        lv.setOnItemClickListener(new OnItemClickListener() 
          public void onItemClick(AdapterView<?> parent, View view,
              int position, long id) 

              // selected item 
              String product = ((TextView) view).getText().toString();

              // Launching new Activity on selecting single List Item
              Intent i = new Intent(getApplicationContext(), SingleListItem.class);
              // sending data to new activity
              i.putExtra("product", product);
              startActivity(i);

          
        );
    

现在在新活动中,我们需要显示从 listview 活动接收到的数据。

    在 res/layout 下创​​建一个新的 xml 文件并将其命名为 single_list_item_view.xml 并键入以下代码。此 XML 文件将用于 SingleListItem.java 的布局

single_list_item_view.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_
  android:layout_>
  <TextView android:id="@+id/product_label"
            android:layout_
            android:layout_
            android:textSize="25dip"
            android:textStyle="bold"
            android:padding="10dip"
            android:textColor="#ffffff"/>    
</LinearLayout>
    现在打开您的第二个活动文件,即 SingleListItem.java 并粘贴以下代码。

SingleListItem.java

package com.androidhive.androidlistview;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

public class SingleListItem extends Activity
    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.single_list_item_view);

        TextView txtProduct = (TextView) findViewById(R.id.product_label);

        Intent i = getIntent();
        // getting attached intent data
        String product = i.getStringExtra("product");
        // displaying selected product name
        txtProduct.setText(product);

    

    最后一步是在 AndroidManifest.xml 文件中添加一个新的活动名称条目。打开你的 AndroidManifest.xml 文件并修改如下代码

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.androidhive.androidlistview"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="8" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".AndroidListViewActivity"
                  android:label="Android List View">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:name=".SingleListItem"
                    android:label="Single Item Selected"></activity>
    </application>
</manifest>
    最后通过右键单击您的项目文件夹 ⇒ 运行方式 ⇒ 1 Android 应用程序来运行您的项目。

【讨论】:

以上是关于为 expandablelistview 的子级创建单独的 onClick() 方法的主要内容,如果未能解决你的问题,请参考以下文章

没有子级的 ExpandableListView 抛出 indexOutOfBoundsException

ExpandableListView实现展开更多和收起更多

BaseExpandableListAdapter 为每个组位置返回相同的子级

将 XElement 的子级转换为字符串 [重复]

具有可变级别数的 ExpandableListView

如何从目标 VC 的子级为协议设置委托?