【问题标题】:accessing a specific view from onclick listener inside getView of customer adapter从客户适配器的 getView 内的 onclick 侦听器访问特定视图
【发布时间】:2013-02-27 00:00:07
【问题描述】:

我希望 onclick 方法与我的布局中的其他视图进行通信。尝试这样做时,我得到了 NullPointerException。我想我可能做错了。

我的getView方法如下:

    public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    ViewHolder holder;
    final int p =position;
    if (v == null) {
       LayoutInflater vi = (LayoutInflater) _c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
       v = vi.inflate(R.layout.menuitemrow, null);
       holder = new ViewHolder();
       holder.image = (ImageView) v.findViewById(R.id.MIR_itemImage);holder.image.setTag(position);
       holder.itemName = (TextView)v.findViewById(R.id.MIR_itemName);holder.itemName.setTag(position);
       holder.itemPrice = (TextView)v.findViewById(R.id.MIR_itemPrice);holder.itemPrice.setTag(position);
       holder.itemOther = (TextView)v.findViewById(R.id.MIR_itemOther);holder.itemOther.setTag(position);
       holder.details = (Button) v.findViewById(R.id.MIR_detailsbtn);holder.details.setTag(position);
       holder.qAdd = (Button) v.findViewById(R.id.MIR_qaddbtn);holder.qAdd.setTag(position);
       v.setTag(holder);
    } else 
        holder = (ViewHolder) v.getTag();
    MenuItemDetail mid = _data.get(position);
    holder.image.setImageResource(mid.icon);
    holder.itemName.setText(mid.itemName);
    holder.itemPrice.setText("Price: $"+mid.itemPrice);
    holder.itemOther.setText(mid.itemOther);
    //set click listeners
    holder.details.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            m =_data.get(p);
            s = m.getItemName();
            Toast.makeText(_c, "clicked details"+p+" "+s, Toast.LENGTH_SHORT).show();
        }
    });
    holder.qAdd.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Toast.makeText(_c, "clicked quick add "+p, Toast.LENGTH_SHORT).show();
            TextView btnUpdate = (TextView) v.findViewById(R.id.CBV_textview2);
            //btnUpdate.setTag(1);
            //btnUpdate.setText(btnUpdate.getTag().toString());
            btnUpdate.setText("b");
        }
    });


    return v;
}

如您所见,我只是为getTag 分配了一个数字,只是为了将它传递给setText 方法。我已经尝试使用 String 注释掉集合并获取。

有问题的行是btnUpdate.setText("b");

有什么想法吗?

总而言之,我正在尝试通过其客户适配器的 getView 方法访问自定义 Button 内的自定义 ButtonTextView

更新评论:

这是与其他按钮一起显示的自定义列表视图。当单击以更新我创建的自定义按钮的文本视图时,我想要列表视图项(自定义ListView 的一部分),该按钮显示在与自定义列表视图相同的活动中。

布局如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<Button
    android:id="@+id/MI_backbutton"
    android:layout_width="fill_parent"
    android:layout_height="50dp"
    android:layout_weight="1"
    android:text="@string/back_list_categories"
    android:textSize="@dimen/FontSize8" />

<ListView
    android:id="@+id/menuList"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="20" >
</ListView>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:layout_gravity="bottom"
    android:layout_marginBottom="5dp"
    android:layout_weight="1" >

    <Button
        android:id="@+id/button2"
        style="@android:style/Widget.Button"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:layout_gravity="bottom"
        android:layout_weight="1"
        android:text="@string/generalbutton" />

    <include
        android:id="@+id/MI_checkorder"
        style="android:buttonStyle"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:layout_gravity="bottom"
        android:layout_marginTop="5dp"
        android:layout_weight="1"
        layout="@layout/custombtnview"
        android:background="@style/AppTheme"
        android:clickable="true"
        android:focusable="true" />

</LinearLayout>

在我引用获取 Textview 的视图中,textview 不存在。该视图中的内容是MI_checkorder。我在想也许这就是我为我的btnUpdate 获得NullPointerException 的原因。 textveiw CBV_textview2 是我作为按钮创建的视图的一部分 (MI_checkorder)。

我现在有了按钮,但无法让更改显示在 UI 上。这是我添加的代码:

            public void onClick(View v) {
            Toast.makeText(_c, "clicked quick add "+p, Toast.LENGTH_SHORT).show();
            TextView btnUpdate = (TextView) inflateToEdit(_c, v).findViewById(R.id.CBV_textview2);
            //btnUpdate.setTag(1);
            //btnUpdate.setText(btnUpdate.getTag().toString());
            btnUpdate.setText("b");
        }

这是我在自定义适配器类中创建的方法。

    public View inflateToEdit(Context c, View view){
    View vw = view;
    LayoutInflater vi = (LayoutInflater) _c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    return vi.inflate(R.layout.custombtnview, null);
}

它正在更新按钮的文本,但它没有显示在 UI 上。我不认为我可以从代码中的这一点更新 UI。我想我需要从活动中做到这一点。

【问题讨论】:

  • 这是在 ListView 中还是什么?请告诉我们更多。通常你可以将一个 OnItemClickListener 分配给一个 AdapterView(就像一个 ListView 持有一个数组适配器),如果我正确理解你的问题,这将使这个过程变得更加简单。
  • 我将问题更新为更清晰

标签: java android android-listview custom-adapter


【解决方案1】:

这是因为在视图上调用的 findViewById 会查找给定视图的子视图。

findViewById doc

“查找具有给定 id 的子视图。如果此视图具有给定 id,则返回此视图。”

据我所知,CBV_textview2 包含在活动的布局中。 所以,你可以做的是将活动传递给适配器的构造函数(我看到你已经有一个 _c 成员变量,我认为它是一个上下文,或者直接传递 CBV_textview2 本身(在包含的活动中调用 findViewById)。

在这两种情况下,您都需要调用活动的 findViewById “从 onCreate(Bundle) 中处理的 XML 中查找由 id 属性标识的视图。”

public class YourAdapter extends ArrayAdapter<String> {
  private final Context context;
  // blahblahblah
  private final TextView mYourTextView;

 public YourAdapter(Context context, String[] values, TextView btnUpdate) {
     super(context, R.layout.rowlayout, values);
     this.context = context;
     this.values = values;
     mYourTextView = btnUpdate;
 }

 ....

 @Override
    public void onClick(View v) {
        Toast.makeText(_c, "clicked quick add "+p, Toast.LENGTH_SHORT).show();
        //mYourTextView.setTag(1);
        //mYourTextView.setText(btnUpdate.getTag().toString());
        mYourTextView.setText("b");
    }

在您的活动中,您应该能够在调用构造函数之前获取 TextView。

【讨论】:

  • 我添加了:TextView btnUpdate = (TextView) inflateToEdit(_c, v).findViewById(R.id.CBV_textview2); 这让我可以充气,现在我有了 textview。但我无法从这里更新。我假设我无法从那里访问 UI 线程。我怎样才能把它发送到隧道上,也许让它调用一个活动的方法来更新它。
  • onClick 回调在 ui 线程内执行。为什么不能从那里更新?什么是 inflateToEdit 方法?该按钮应该已经在您的活动的 setContentView 中膨胀。
  • 那是因为你正在膨胀一个新的 custombtnview。您需要引用您的一项活动。你不能把它传递给你的适配器的构造函数吗?
  • 我愿意,但是当我尝试findViewById 它返回一个空引用并且我得到了异常。我不知道为什么这条线:TextView btnUpdate = (TextView) v.findViewById(R.id.CBV_textview2); 不起作用。所以这就是我将代码更改为您刚刚看到的内容的时候。我将删除它,因为我正在创建一个新的 custombtnview。我只是认为,因为我必须在列表视图中的自定义行的获取视图中执行此操作,因此我必须为此执行此操作,因为它是我创建的自定义视图按钮。
  • 只需在活动的 onCreate 中有 findViewById 并将 TextView 传递给适配器的构造函数。
猜你喜欢
  • 1970-01-01
  • 2014-02-26
  • 1970-01-01
  • 1970-01-01
  • 2014-01-05
  • 1970-01-01
  • 1970-01-01
  • 2017-05-06
  • 1970-01-01
相关资源
最近更新 更多