簡體   English   中英

以編程方式將TextView添加到Listview自定義行

[英]Add TextView programatically to Listview custom row

我想以編程方式將一個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在每一行中出現多次。 我究竟做錯了什么? 謝謝

我真正想做的是在某些條件下添加一個Textview,否則添加一些ImageView,因此我無法在XML文件中聲明它。

您應該使用多個布局來正確執行此操作,因為在行的布局中添加和刪除視圖可能既昂貴又緩慢。 您可以使用XML或Java創建不同的布局,但是在適配器中,您必須重寫getViewTypeCount()getItemViewType()才能告訴適配器期望不止一個布局以及用於每一行的布局。

這很簡單,我在以下示例中編寫了一個示例: 在Android Listview中重用具有2種不同布局的視圖


原版的

但是,TextView在每一行中出現多次。 我究竟做錯了什么?

您無法說明ListView回收其行的方式。 Google I / O演示文稿(如Turbo-Charge Your UI)中對此進行了詳細說明。

也許您應該只將多余的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;
}

每當操作系統要呈現視圖時,都會調用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;
}

順便說一句,您可以通過將文本視圖添加到R.layout.row來消除動態添加文本視圖的需要。

您似乎無條件地添加了TextView,對嗎?

問題是,如何確定必須在其中添加一行的一行。 也許借助於position參數? 只有你知道。

我注意到您正在添加TextView而不管convertView是否為null。 這可以解釋一個事實,即任何一行中可能都有多個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...");

這是給您的示例代碼。 首先,您必須確定將數據發送到適配器的格式。 在我的代碼中,我將其作為數組列表發送。

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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM