簡體   English   中英

Android Viewholder類范圍廣泛

[英]Android viewholder class wide scope

我有一個使用Viewholder模式的列表適配器,我的問題是我需要從同一類中包含的AsyncTask的onpostexecute()中的Viewholder中更新一個TextView,但這總是在TextView上返回一個nullpointer,如何給我的textviews從足夠的視野持有人,我可以在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();
    }


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


        }

    }
}
}

Java是按值傳遞的,但是您可以在值中發送對象的引用。 我已經使用了上面的內容,並將持有人的參考發送給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);


        }

    }
}
}

讓我們在這里和那里改變一些事情:)

讓我們將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,問題和所有者,並且為了將該信息傳遞給其他對象,我們不應該使用全局值(可以通過以下方式更改它們)每個過程),請考慮一下當您的調用“ apiHelper.submitAnswer(submitId,submitQuestion)”需要花費很長時間(例如半秒鍾),然后用戶在半秒鍾內單擊第一個答案並在第三個問題上回答c時的情況,通過全局傳遞值,您無法確定要接受的最高答案:)

干杯:)

暫無
暫無

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

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