如何在单独的视图中获取TextView的OnClick事件?

时间:2016-07-12 03:43:24

标签: java android android-layout android-activity

我有一个小应用程序,它使用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的点击事件。

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

编辑:

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

2 个答案:

答案 0 :(得分:1)

从活动中删除所有tv_cardDesc相关代码,包括onClickListener&amp; findViewById

像这样更改getView CustomAdapter方法:

@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;
}

说明:

  

您已完成findViewByID的{​​{1}}   TextView所以不需要这样做CustomAdapter只需在此处执行此操作即可   主要内容:如果您需要接口实现,则无法直接访问活动中的适配器视图   的ListView 即可。但对于您的问题,上述解决方案是最好的。!!

答案 1 :(得分:1)

像这样编辑您的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;
}
}