我想以编程方式将一个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;
}
然而,TextView在每一行中出现多次。 我究竟做错了什么?感谢
答案 0 :(得分:5)
我真正想要做的是在某些条件下添加Textview,否则添加一些ImageView,所以我不能在XML文件中声明它。
您应该使用多个布局来正确执行此操作,因为在行的布局中添加和删除视图可能既昂贵又缓慢。您可以使用XML或Java创建不同的布局,但是在适配器中,必须覆盖getViewTypeCount()
和getItemViewType()
,以告知适配器需要多个布局以及哪个布局为用于每一行。
这很简单,我在Reusing views in Android Listview with 2 different layouts
中写了一个例子原创
然而,TextView在每一行中出现多次。我做错了什么?
您未能解释ListView回收行的方式。这在Google {/ 3}}等Google I / O演示文稿中有详细说明。
也许您只需将额外的TextView添加到行的XML布局或使用多个布局。由于您没有解释为什么要添加TextView,因此很难给出明确的建议。
这只为每行添加一个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;
}
答案 1 :(得分:1)
如果切换到仅在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;
}
顺便说一句,您可以通过将文本视图添加到R.layout.row来删除动态添加textview的需要
答案 2 :(得分:0)
您似乎无条件地添加了TextView,对吧?
问题是,如何识别必须添加的单行。也许通过position
参数?只有你知道。
答案 3 :(得分:0)
我注意到,无论TextView
是否为空,您都要添加convertView
。这可以解释任何一行中可能包含多个TextView
小部件的事实。
但是,我同意以前的答案 - 可能有更好的方法来完成你需要的东西。
答案 4 :(得分:0)
我的猜测是,当视图被回收时,它已经添加了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...");
答案 5 :(得分:0)
以下是您的示例代码。首先,您必须决定将数据发送到适配器的格式。在我的代码中,我将其作为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;
}
只有在您拥有特定数据顺序(例如“列表”)后,您才能在列表视图中逐行迭代数据。
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View row = convertView;
if (row == null)
{
// get reference to the activity
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
// Inflate the custom text which will replace the default text view
//list_item is a simple lineer layout which contain textView1 in it.
row = inflater.inflate(R.layout.list_item, parent, false);
}
// Create custom text view to customize
TextView tv = (TextView) row.findViewById(R.id.textView1);
// TextView can be customized here or in the xml file
tv.setText(list.get(position));
return row;
}
}
最后,您可以像这样调用自定义适配器;
CustomArrayAdapter adapter = new CustomArrayAdapter(getActivity(),
R.id.textView1,values);