[英]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.