Android viewholder类范围广

时间:2015-10-06 19:13:38

标签: java android android-viewholder

我有一个使用视图模式的列表适配器,我的问题是我需要在同一个类中包含的AsyncTask的onpostexecute()中从viewholder更新一个TextView,但这总是在TextView上返回一个nullpointer,怎么能从viewholder给我的textviews足够的范围,我可以在AsyncTask中更改它们吗?我将在下面添加一个代码示例,感谢adcvance

public class ListAdapter extends BaseAdapter {


TextView tvA1, tvA2;

Integer submitId;
String submitQuestion;

public ListAdapter() {

  ....

}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    friendsViewHolder holder = null;


    if (convertView == null) {

        holder = new friendsViewHolder();

        convertView = inflater.inflate(R.layout.list_item_status, null);


        holder.tvA1 = (TextView) convertView
                .findViewById(R.id.tvA1);
        holder.tvA2 = (TextView) convertView
                .findViewById(R.id.tvA2);
        holder.btQ1 = (LinearLayout) convertView
                .findViewById(R.id.btConfirm);
        holder.btQ2 = (LinearLayout) convertView
                .findViewById(R.id.btDeny);



        convertView.setTag(holder);
    } else {
        holder = (friendsViewHolder) convertView.getTag();
    }


    tvA1 = holder.tvA1;
    tvA2 = holder.tvA2;

    holder.btQ1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            submitId = id;
            submitQuestion = q1;

            new UpdateAnswer().execute();


        }
    });

    holder.btQ2.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            submitId = id;
            submitQuestion = q2;

            new UpdateAnswer().execute();

        }
    });

    return convertView;


}

static class friendsViewHolder {

    TextView tvA1, tvA2;
    LinearLayout btQ1, btQ2;

}

private class UpdateAnswer extends AsyncTask<Void, Void, ArrayList<Object>> {


    @Override
    protected ArrayList<Object> doInBackground(Void... params) {

        return apiHelper.submitAnswer(submitId, submitQuestion);

    }

    @Override
    protected void onPostExecute(ArrayList<Object> answers) {
        super.onPostExecute(answers);

        if (answers != null) {

            Integer a1 = (Integer) answers.get(1);
            Integer a2 = (Integer) answers.get(2);

            //Error here
            tvA1.setText(a1);
            tvA1.setVisibility(View.VISIBLE);

            //error here
            tvA2.setText(a2);
            tvA2.setVisibility(View.VISIBLE);


        }

    }
}
}

2 个答案:

答案 0 :(得分:1)

Java是按值传递的,但您可以在值中发送Object的引用。我已经使用了上面的内容,并将持有者的引用发送给了AsyncTask。

public class ListAdapter extends BaseAdapter {


TextView tvA1, tvA2;

Integer submitId;
String submitQuestion;

public ListAdapter() {

  ....

}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    friendsViewHolder holder = null;


    if (convertView == null) {

        holder = new friendsViewHolder();

        convertView = inflater.inflate(R.layout.list_item_status, null);


        holder.tvA1 = (TextView) convertView
                .findViewById(R.id.tvA1);
        holder.tvA2 = (TextView) convertView
                .findViewById(R.id.tvA2);
        holder.btQ1 = (LinearLayout) convertView
                .findViewById(R.id.btConfirm);
        holder.btQ2 = (LinearLayout) convertView
                .findViewById(R.id.btDeny);



        convertView.setTag(holder);
    } else {
        holder = (friendsViewHolder) convertView.getTag();
    }


    holder.btQ1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            submitId = id;
            submitQuestion = q1;

            new UpdateAnswer(holder).execute();


        }
    });

    holder.btQ2.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            submitId = id;
            submitQuestion = q2;

            new UpdateAnswer().execute();

        }
    });

    return convertView;


}

static class friendsViewHolder {

    TextView tvA1, tvA2;
    LinearLayout btQ1, btQ2;

}

private class UpdateAnswer extends AsyncTask<Void, Void, ArrayList<Object>> {
     friendsViewHolder holder;

    UpdateAnswer(friendsViewHolder holder)
    {
        this.holder = holder;
    }

    @Override
    protected ArrayList<Object> doInBackground(Void... params) {

        return apiHelper.submitAnswer(submitId, submitQuestion);

    }

    @Override
    protected void onPostExecute(ArrayList<Object> answers) {
        super.onPostExecute(answers);

        if (answers != null) {

            Integer a1 = (Integer) answers.get(1);
            Integer a2 = (Integer) answers.get(2);

            //Error here
            holder.tva1.setText(a1);
            holder.tva1.setVisibility(View.VISIBLE);

            //error here
            holder.tva2.setText(a2);
            holder.tva2.setVisibility(View.VISIBLE);


        }

    }
}
}

答案 1 :(得分:1)

让我们在这里和那里改变一些事情:)

让我们将friendsViewHolder公之于众,我还需要在java中添加它,以某种方式自定义名称以名称以cammel开头的类只是简单地放入FirstLetterOfEeachWordIsBig:)

让我们将构造函数添加到Update任务:)

private class UpdateAnswer extends AsyncTask<Void, Void, ArrayList<Object>> {
    int submitId;
    String submitQuestion;
    friendsViewHolder holder;

    public UpdateAnswer (int submitId, String submitQuestion, friendsViewHolder holder) {
        this.submitId = submitId;
        this.submitQuestion = submitQuestion;
        this.holder = holder;
    }

点击即可更改为

  final frendsViewHolder finalHolder = holder;
  holder.btQ1.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        new UpdateAnswer(id, q1, finalHolder).execute();
    }
});

我们不再需要全局TvA1,tvA2,submitId,submitQuestion;

最后我们需要编辑onPostExecute,我认为因为你有持有者价值转发所以要这么努力:)

        holder.tvA1.setText(a1);
        holder.tvA1.setVisibility(View.VISIBLE);

        holder.tvA2.setText(a2);
        holder.tvA2.setVisibility(View.VISIBLE);

在java中,您可以创建构造函数以允许将其他数据传递给对象,我们使用它来为我们的任务设置id,问题和持有者,并且为了将该信息传递给其他对象,我们应该使用全局值(它们可以被每个过程改变),在你的电话时考虑情况&#34; apiHelper.submitAnswer(submitId,submitQuestion)&#34;需要很长时间才能继续(例如半秒),然后用户在半秒内点击答案,然后在3个问题上回答c,通过全局传递值,你无法确定接受的答案:)

干杯:)