Android 以编程方式将TextView添加到Listview自定义行

Android 以编程方式将TextView添加到Listview自定义行,android,android-listview,android-linearlayout,textview,baseadapter,Android,Android Listview,Android Linearlayout,Textview,Baseadapter,我想以编程方式将一个TextView添加到XML文件中声明的Linearlayout,该文件定义了应用于所有listview行的自定义行。 为此,我有以下代码: <LinearLayout android:id="@+id/zv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/title" a

我想以编程方式将一个TextView添加到XML文件中声明的Linearlayout,该文件定义了应用于所有listview行的自定义行。 为此,我有以下代码:

<LinearLayout
    android:id="@+id/zv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignTop="@+id/title"
    android:layout_marginBottom="1dip"
    android:layout_marginLeft="5dip"
    android:layout_marginRight="5dip"
    android:orientation="vertical"
    android:padding="1dip" >
</LinearLayout>

class ListViewAdapter extends BaseAdapter {

(...)
public View getView(int position, View convertView, ViewGroup parent) {
        View vi=convertView;
        if (convertView == null)
            vi = inflater.inflate(R.layout.row, null);

        TextView tv_nz = new TextView(activity.getApplicationContext());

        LinearLayout zv = (LinearLayout)vi.findViewById(R.id.zv);

        tv_nz.setText("testing...");
        zv.addView(tv_nz);
(...)

return vi;
}

类ListViewAdapter扩展了BaseAdapter{
(...)
公共视图getView(int位置、视图转换视图、视图组父视图){
视图vi=转换视图;
if(convertView==null)
vi=充气机充气(R.layout.row,空);
TextView tv_nz=新的TextView(activity.getApplicationContext());
LinearLayout zv=(LinearLayout)vi.findViewById(R.id.zv);
tv_nz.setText(“测试…”);
zv.addView(新西兰电视台);
(...)
返回vi;
}
但是,文本视图在每一行中出现不止一次。 我做错了什么?谢谢

我真正想做的是在某些条件下添加一个Textview,在其他情况下添加一些ImageView,这样我就不能在XML文件中声明它

您应该使用多个布局来正确执行此操作,因为在一行的布局中添加和删除视图可能既昂贵又缓慢。您可以用XML或Java创建不同的布局,但在适配器中必须覆盖
getViewTypeCount()
getItemViewType()
告诉适配器需要多个布局以及每行使用哪个布局

这很简单,我在中写了一个例子:


原创

但是,文本视图在每一行中出现不止一次。我做错了什么

您无法解释ListView回收行的方式。这在Google I/O演示文稿(如)中有详细解释

也许您应该简单地将额外的TextView添加到行的XML布局中,或者使用多个布局。很难给出明确的建议,因为您还没有解释为什么要添加TextView


这将仅向每行添加一个文本视图:

public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        // Code here only affects new rows
        convertView = inflater.inflate(R.layout.row, null);

        TextView tv_nz = new TextView(activity.getApplicationContext());
        tv_nz.setText("testing...");
        convertView.addView(tv_nz);
    }
    else {
        // Code here affects only recycled rows
    }

    // Code here affects every row when the ListView is scrolled
    return convertView;
}
我真正想做的是在某些条件下添加一个Textview,在其他情况下添加一些ImageView,这样我就不能在XML文件中声明它

您应该使用多个布局来正确执行此操作,因为在一行的布局中添加和删除视图可能既昂贵又缓慢。您可以用XML或Java创建不同的布局,但在适配器中必须覆盖
getViewTypeCount()
getItemViewType()
告诉适配器需要多个布局以及每行使用哪个布局

这很简单,我在中写了一个例子:


原创

但是,文本视图在每一行中出现不止一次。我做错了什么

您无法解释ListView回收行的方式。这在Google I/O演示文稿(如)中有详细解释

也许您应该简单地将额外的TextView添加到行的XML布局中,或者使用多个布局。很难给出明确的建议,因为您还没有解释为什么要添加TextView


这将仅向每行添加一个文本视图:

public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        // Code here only affects new rows
        convertView = inflater.inflate(R.layout.row, null);

        TextView tv_nz = new TextView(activity.getApplicationContext());
        tv_nz.setText("testing...");
        convertView.addView(tv_nz);
    }
    else {
        // Code here affects only recycled rows
    }

    // Code here affects every row when the ListView is scrolled
    return convertView;
}

您似乎无条件地添加了TextView,对吗


问题是,您如何识别必须添加的单行。可能通过
位置
参数?只有您知道。

您似乎无条件地添加TextView,对吗


问题是,您如何识别必须添加的单行。可能通过
位置
参数?只有您知道。

我注意到您正在添加
TextView
,而不管
convertView
是否为空。这可以解释任何一行都可能有多个
TextView
其中的小部件


但是,我同意前面的答案-可能有更好的方法来完成您需要的内容。

我注意到您正在添加一个
TextView
,而不管
convertView
是否为空。这可能解释了任何一行中都可能包含多个
TextView
小部件的事实


但是,我同意前面的答案-可能有一种更好的方法来实现您的需求。

我的猜测是,当视图被回收时,它已经添加了TextView,因此当您添加另一个视图时,您不会检查是否已经从以前的视图添加了TextView。类似的内容应该帮助:

//after your view inflation
LinearLayout zv = (LinearLayout)vi.findViewById(R.id.zv);
TextView tv_nz;
if(zv.getChildCount() == 0) {
    tv_nz = new TextView(activity.getApplicationContext());
    zv.addView(tv_nz);
} else
    tv_nz = (TextView) zv.getChildAt(0);
tv_nz.setText("testing...");

我的猜测是,当视图被回收时,它已经添加了TextView,因此,当您要添加另一个视图时,您不会检查是否已经从以前的视图添加了一个。类似这样的操作应该会有所帮助:

//after your view inflation
LinearLayout zv = (LinearLayout)vi.findViewById(R.id.zv);
TextView tv_nz;
if(zv.getChildCount() == 0) {
    tv_nz = new TextView(activity.getApplicationContext());
    zv.addView(tv_nz);
} else
    tv_nz = (TextView) zv.getChildAt(0);
tv_nz.setText("testing...");

每次操作系统希望呈现视图时,都会调用getView。这意味着每次listview请求行的内容时,都会添加一个新视图

如果在convertView不为null时切换到仅添加视图,则可以实现所需的功能

public View getView(int position, View convertView, ViewGroup parent) {
    TextView tv_nz;

    // If the row does not exist, lets create it.
    if (convertView == null) {
        convertView = inflater.inflate(R.layout.row, null); 

        // Add the text view to the new view
        tv_nz = new TextView(activity.getApplicationContext());
        tv_nz.setId(R.id.tv_nz);

        convertView.addView(tv_nz);
    } else {
        // The row already exists, lets find the TextView
        tv_nz = (TextView) findViewById(R.id.tv_nz);
    }

    if (tv_nz != null) {
        tv_nz.setText("testing...");
    }

    return convertView;
}

顺便说一句,您可以通过将textview添加到R.layout中来消除动态添加textview的需要。每当操作系统想要呈现视图时,都会调用行

getView。这意味着每次listview请求行的内容时,您都在添加新视图

如果在convertView不为null时切换到仅添加视图,则可以实现所需的功能

public View getView(int position, View convertView, ViewGroup parent) {
    TextView tv_nz;

    // If the row does not exist, lets create it.
    if (convertView == null) {
        convertView = inflater.inflate(R.layout.row, null); 

        // Add the text view to the new view
        tv_nz = new TextView(activity.getApplicationContext());
        tv_nz.setId(R.id.tv_nz);

        convertView.addView(tv_nz);
    } else {
        // The row already exists, lets find the TextView
        tv_nz = (TextView) findViewById(R.id.tv_nz);
    }

    if (tv_nz != null) {
        tv_nz.setText("testing...");
    }

    return convertView;
}

顺便说一句,您可以通过将textview添加到R.layout.row中来消除动态添加textview的需要。下面是一个示例代码。首先,您必须确定将数据发送到适配器的格式。在我的代码中,我将其作为arraylist发送

public class CustomArrayAdapter extends ArrayAdapter<String>
{
    ArrayList<String> list;
    Context mContext; // ADD THIS to keep a context

public CustomArrayAdapter(Context context, int textViewResourceId,
        ArrayList<String> objects)
{
    super(context, textViewResourceId, objects);
    this.mContext = context;
    // Pass the elements in the list
    list = objects;
}
最后,您可以像这样调用自定义适配器

 CustomArrayAdapter adapter = new CustomArrayAdapter(getActivity(),
            R.id.textView1,values);

这是一个示例代码。首先,您必须决定将数据发送到适配器的格式。在我的代码中,我将其作为arraylist发送

public class CustomArrayAdapter extends ArrayAdapter<String>
{
    ArrayList<String> list;
    Context mContext; // ADD THIS to keep a context

public CustomArrayAdapter(Context context, int textViewResourceId,
        ArrayList<String> objects)
{
    super(context, textViewResourceId, objects);
    this.mContext = context;
    // Pass the elements in the list
    list = objects;
}
最后,您可以像这样调用自定义适配器

 CustomArrayAdapter adapter = new CustomArrayAdapter(getActivity(),
            R.id.textView1,values);

您可以使用android:visibility=“gone”
作为文本视图的