【问题标题】:How to get OnClick event of TextView in separate view?如何在单独的视图中获取 TextView 的 OnClick 事件?
【发布时间】:2016-07-12 12:55:49
【问题描述】:

我有一个小型应用程序,它使用 AsyncTask 调用 Web 服务,并根据返回的结果填充自定义数组适配器。

由于这是与我的活动正在使用的视图不同的视图,因此当我尝试设置 onClickListener 时,我不断收到以下错误,我收到以下错误:

Unable to start activity ComponentInfo{com.lorentzos.swipecards.example/com.lorentzos.swipecards.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setOnClickListener(android.view.View$OnClickListener)' on a null object reference

这对我来说很有意义,但我不确定如何解决它。这是我的代码。

我的活动使用以下布局,但上面没有我的 TextView:

setContentView(R.layout.activity_main);

当 Web 服务返回项目时,我使用结果填充 arraydapter,并且该 arraydapter 使用不同的布局来显示结果。

arrayAdapter = new CustomAdapter(getApplicationContext(), R.layout.tradingcard, result);

我的 onClickListener 看起来像这样,它在我的活动 onCreate() 方法中:

TextView cardDesc = (TextView) this.findViewById(R.id.tv_cardDesc);
        cardDesc.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //open up a fragment to display the entire carddescription
                //makeToast(getApplicationContext(), "Test description click");
            }
        });

提前感谢您的帮助!我真的很困惑如何从我的活动中访问这个 TextView 的点击事件。

另一个问题:我正在尝试访问点击事件,以便我可以打开一个弹出窗口或片段以显示更多信息,例如点击。这是一个描述字段,因此它可以有很多文本,但应用程序上只会显示几行,然后当用户单击描述时,它应该在另一个片段上打开该字段以显示整个文本并可以滚动.最好的方法是什么?创建一个打开的新片段?

编辑:

activity_main.xml:

<merge
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <com.lorentzos.flingswipe.SwipeFlingAdapterView
        android:id="@+id/frame"
        android:background="#d1d1d1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:rotation_degrees="15.5"
        tools:context=".MainActivity"
        android:layout_gravity="top"/>

    <TextView
        android:id="@+id/tv_noCardsLabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:textStyle="bold"
        android:textSize="18sp"
        android:textColor="#474747"
        android:textAlignment="center"
        tools:text="No Cards Left to Swipe!"
        android:layout_gravity="center" />

    <include layout="@layout/buttons" />
</merge>

tradingcard.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_gravity="top"
    android:layout_width="match_parent"
    android:layout_height="415dp"
    android:padding="5dp"
    android:layout_marginTop="20dp">

    <LinearLayout
        android:id="@+id/outerMainCardLayout"
        android:layout_width="match_parent"
        android:layout_height="400dp"
        android:layout_gravity="center_horizontal|top"
        android:orientation="vertical"
        android:background="@drawable/swipecard_shadow"
        android:gravity="top"
        android:layout_marginLeft="5dp">

        <LinearLayout
            android:id="@+id/mainCardLayout"
            android:layout_width="match_parent"
            android:layout_height="400dp"
            android:layout_gravity="center_horizontal|top"
            android:orientation="vertical"
            android:weightSum="1"
            android:background="#FFFFFF"
            android:gravity="top">

            <TextView
                android:id="@+id/tv_cardTitle"
                android:background="#ffffff"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="10dp"
                android:textStyle="bold"
                android:textSize="16sp"
                android:textColor="#505353"
                android:textAlignment="center"
                tools:text="Cement Pouring Guy"
                android:layout_gravity="center_horizontal"/>

            <TextView
                android:id="@+id/tv_companyName"
                android:background="#ffffff"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="14sp"
                android:textColor="#505353"
                android:textAlignment="center"
                tools:text="ABC Company"
                android:layout_gravity="center_horizontal" />

            <TextView
                android:id="@+id/tv_cardDesc"
                android:textSize="14sp"
                android:textColor="#505353"
                android:background="#e6e7e8"
                android:layout_width="match_parent"
                android:layout_height="150dp"
                android:padding="15dp" />

        </LinearLayout>
    </LinearLayout>

    <View
        android:id="@+id/item_swipe_left_indicator"
        android:alpha="0"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_margin="20dp"
        android:background="#FFFFFF" />

    <View
        android:id="@+id/item_swipe_right_indicator"
        android:alpha="0"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_margin="20dp"
        android:layout_gravity="right"
        android:background="#FFFFFF" />

</FrameLayout>

自定义适配器:

public class CustomAdapter extends ArrayAdapter<Card> {
    private final Context context;
    private final ArrayList<Card> card;
    private final int layoutResourceId;

    public CustomAdapter(Context context, int layoutResourceId, ArrayList<Card> cards) {
        super(context, layoutResourceId, cards);
        this.context = context;
        this.cards = cards;
        this.layoutResourceId = layoutResourceId;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = convertView;
        ViewHolder holder = null;

        LayoutInflater inflater = (LayoutInflater) context.getSystemService((Activity.LAYOUT_INFLATER_SERVICE));

        if (view == null) {
            view = inflater.inflate(layoutResourceId, parent, false);

            holder = new ViewHolder();
            holder.title = (TextView)view.findViewById(R.id.tv_cardTitle);
            holder.companyname = (TextView)view.findViewById(R.id.tv_companyName);
            holder.description = (TextView)view.findViewById(R.id.tv_cardDesc);

            view.setTag(holder);
        } else {
            holder = (ViewHolder)view.getTag();
        }

        Card j = cards.get(position);

        holder.title.setText(j.getCardTitle());
        holder.companyname.setText(j.getCompanyName());
        holder.description.setText(j.getDescription());

        return view;
    }

    static class ViewHolder
    {
        TextView title;
        TextView companyname;
        TextView description;
    }
}

【问题讨论】:

  • 我能看到你的activity_main.xmltradingcard.xmlCustomAdapter 代码吗?请编辑问题并附上它..!!
  • 您可以使用意图将数据从一个活动传递到另一个活动
  • @jankigadhiya 添加了您要求的代码!感谢您的帮助!
  • @user2573690 tv_cardDesc 在适配器中你不能直接在活动中做findViewById()。最好在CustomAdapter 中访问它,或者要求您只需要访问活动中的点击??您只需要打开Fragment 对吗?你也可以在适配器中做..!!
  • 在@user2573690下方查看我的回答

标签: java android android-layout android-activity


【解决方案1】:

从活动中删除所有与tv_cardDesc相关的代码,包括onClickListenerfindViewById

像这样更改CustomAdaptergetView 方法:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View view = convertView;
    ViewHolder holder = null;

    LayoutInflater inflater = (LayoutInflater) context.getSystemService((Activity.LAYOUT_INFLATER_SERVICE));

    if (view == null) {
        view = inflater.inflate(layoutResourceId, parent, false);

        holder = new ViewHolder();
        holder.title = (TextView)view.findViewById(R.id.tv_cardTitle);
        holder.companyname = (TextView)view.findViewById(R.id.tv_companyName);
        holder.description = (TextView)view.findViewById(R.id.tv_cardDesc);

        view.setTag(holder);
    } else {
        holder = (ViewHolder)view.getTag();
    }

    Card j = cards.get(position);

    holder.title.setText(j.getCardTitle());
    holder.companyname.setText(j.getCompanyName());
    holder.description.setText(j.getDescription());

    // JUST DEFINE THE CLICK LISTENER HERE

    holder.description.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //open up a fragment to display the entire carddescription
            //makeToast(getApplicationContext(), "Test description click");
            Toast.makeText(contex, "Test description click :"+position, Toast.LENGTH_SHORT).show();
        }
    });

    return view;
}

说明:

你已经为TextView 完成了findViewByID in CustomAdapter 所以没必要这样做 Activity 就在这里做 & 主要内容:如果需要,您不能直接在活动中访问适配器的视图,因此您需要一个 接口实现 列表视图。但是对于您的问题,上述解决方案是最好的。!

【讨论】:

  • 谢谢!那行得通,所以我只是在活动中定义了 onClickListener,而它应该在适配器本身中。现在说得通了!
【解决方案2】:

像这样编辑您的 CustomAdapter

public class CustomAdapter extends ArrayAdapter<Card> {
private final Context context;
private final ArrayList<Card> card;
private final int layoutResourceId;

public CustomAdapter(Context context, int layoutResourceId, ArrayList<Card> cards) {
    super(context, layoutResourceId, cards);
    this.context = context;
    this.cards = cards;
    this.layoutResourceId = layoutResourceId;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View view = convertView;
    ViewHolder holder = null;

    LayoutInflater inflater = (LayoutInflater) context.getSystemService((Activity.LAYOUT_INFLATER_SERVICE));

    if (view == null) {
        view = inflater.inflate(layoutResourceId, parent, false);

        holder = new ViewHolder();
        holder.title = (TextView)view.findViewById(R.id.tv_cardTitle);
        holder.companyname = (TextView)view.findViewById(R.id.tv_companyName);
        holder.description = (TextView)view.findViewById(R.id.tv_cardDesc);

   holder.title.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //your code to do
        }
   });
   holder.companyname.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //your code to do
        }
   });
   holder.description.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //your code to do
        }
   });

        view.setTag(holder);
    } else {
        holder = (ViewHolder)view.getTag();
    }

    Card j = cards.get(position);

    holder.title.setText(j.getCardTitle());
    holder.companyname.setText(j.getCompanyName());
    holder.description.setText(j.getDescription());

    return view;
}

static class ViewHolder
{
    TextView title;
    TextView companyname;
    TextView description;
}
}

【讨论】:

  • 你的回答和我的回答有什么区别??我错过了你添加的东西吗??
  • 没什么兄弟......当我编辑我的答案时,你发布了你的答案。在我发布我的答案后,我发现我们是一样的............我不知道该怎么做......如果有任何错误......请原谅我......
猜你喜欢
  • 1970-01-01
  • 2013-04-19
  • 2023-03-18
  • 2011-07-19
  • 1970-01-01
  • 2018-03-01
  • 2013-07-15
  • 1970-01-01
相关资源
最近更新 更多