我正在使用Json数据创建列表视图。我正在填充一些图像,文本字段和一个按钮。当用户点击按钮按钮时,标题会发生变化。
问题是如果按钮被修改并且用户滚动,列表视图按钮将重置为第一状态。请查看此视频,最好先解释一下:https://www.youtube.com/watch?v=57ZraP7ED2E&feature=youtu.be
适配器
public class FilmRequestAdapter extends ArrayAdapter<FilmRequest>{
Context context;
List<FilmRequest> data;
public FilmRequestAdapter(Context context, int resource, List<FilmRequest> objects) {
super(context, resource, objects);
// TODO Auto-generated constructor stub
this.context=context;
this.data=objects;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row=convertView;
if (row==null) {
LayoutInflater inflater=((Activity)context).getLayoutInflater();
row=inflater.inflate(R.layout.film_request_list,null);
}
((TextView)row.findViewById(R.id.FilmRequestFilmTitle)).setText(((FilmRequest)data.get(position)).title);
((TextView)row.findViewById(R.id.FilmRequestRating)).setText("Imdb Puanı : "+((FilmRequest)data.get(position)).rating);
((TextView)row.findViewById(R.id.FilmRequestOrder)).setText("Sıra : "+((FilmRequest)data.get(position)).order);
((TextView)row.findViewById(R.id.FilmRequestVoteCount)).setText("Oya adeti : "+((FilmRequest)data.get(position)).voteCount);
Button button=(Button)row.findViewById(R.id.FilmRequestActionButton);
String status=((FilmRequest)data.get(position)).status;
boolean requested=((FilmRequest)data.get(position)).requested;
boolean voted=((FilmRequest)data.get(position)).voted;
if (status.equalsIgnoreCase("A") || status.equalsIgnoreCase("")) {
if (requested) {
if (voted) {
button.setText("Oylanmış");
button.setEnabled(false);
}else {
button.setText("+ Oyla");
button.setEnabled(true);
button.setTag(R.string.film_request_action, "VOTEABLE");
button.setTag(R.string.film_request_id,((FilmRequest)data.get(position)).id);
}
} else {
button.setText("Filmi İste");
button.setEnabled(true);
button.setTag(R.string.film_request_action, "REQUESTABLE");
button.setTag(R.string.film_request_id,((FilmRequest)data.get(position)).imdbId);
}
} else {
button.setText("Eklenmiş");
button.setEnabled(false);
}
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
FilmRequestActivity.ButtonClickFunction(context,(Button)v);
}
});
((ImageView)row.findViewById(R.id.FilmRequestPoster)).setImageBitmap(((FilmRequest)data.get(position)).bm);
return row;
}
}
异步类
public class FilmRequestAsync extends AsyncTask<String, Void, List<FilmRequest>>{
Context context;
ListView listView;
private ProgressDialog progressDialog;
public FilmRequestAsync (Context context) {
this.context=context;
this.listView=(ListView) ((Activity)context).findViewById(R.id.FilmRequestList);
}
protected void onPreExecute() {
this.progressDialog = ProgressDialog.show(context, "Lütfen Bekleyin...", "Fimler Yükleniyor...",true);
}
@Override
protected List<FilmRequest> doInBackground(String... params) {
Log.d("debug","FilmRequestAsync param[0]"+params[0]);
List<FilmRequest> filmRequests=null;
String jsonString;
try {
jsonString=GeneralFunctions.getUrl(params[0]);
if (jsonString!=null) {
filmRequests=this.getFilmRequestListFromJsonString(jsonString);
}
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return filmRequests;
}
private List<FilmRequest> getFilmRequestListFromJsonString(String jsonString){
List<FilmRequest> filmRequests=new ArrayList<FilmRequest>();
try {
Log.d("debug","Json Verisi oluşturuluyor.");
JSONArray json=new JSONArray(jsonString);
Log.d("debug","Json Verisi Oluşturuldu");
int i;
for (i=0;i<json.length();i++) {
JSONObject tmpJson=(JSONObject)json.get(i);
filmRequests.add(
new FilmRequest(
tmpJson.getString("id"),
tmpJson.getString("imdb_id"),
tmpJson.getString("poster"),
tmpJson.getString("title"),
tmpJson.getString("rating"),
tmpJson.getString("order"),
tmpJson.getString("status"),
tmpJson.getString("vote_count"),
tmpJson.getBoolean("requested"),
tmpJson.getBoolean("voted")
)
);
tmpJson=null;
}
} catch (JSONException e) {
Log.d("debug","Json Verisi HATASI:");
filmRequests=null;
e.printStackTrace();
}
return filmRequests;
}
@Override
protected void onPostExecute(List<FilmRequest> result) {
this.progressDialog.dismiss();
if (result==null) return;
// TODO Auto-generated method stub
super.onPostExecute(result);
Log.d("debug", "FilmRequestAsync onPostExecute Başı");
FilmRequestAdapter filmRequestAdapter=new FilmRequestAdapter(context, R.layout.film_request_list, result);
Log.d("debug","FilmRequestAsync:Adapter set ediliyor.");
listView.setAdapter(filmRequestAdapter);
Log.d("debug", "onPostExecute Sonu");
}
}
列出Xml文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/film_container"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:background="@drawable/film_list_style"
android:orientation="horizontal"
android:padding="3dp" >
<!-- ListRow Left sied Thumbnail image -->
<!-- Title Of Song-->
<!-- Artist Name -->
<!-- Rightend Duration -->
<ImageView
android:id="@+id/FilmRequestPoster"
android:layout_width="83dp"
android:layout_height="106dp" />
<Button
android:id="@+id/FilmRequestActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:text="+ Oyla" />
<TextView
android:id="@+id/FilmRequestRating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/FilmRequestFilmTitle"
android:layout_below="@+id/FilmRequestFilmTitle"
android:text="Rating" />
<TextView
android:id="@+id/FilmRequestVoteCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/FilmRequestOrder"
android:layout_below="@+id/FilmRequestOrder"
android:text="VoteCount" />
<TextView
android:id="@+id/FilmRequestFilmTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/FilmRequestActionButton"
android:layout_toRightOf="@+id/FilmRequestPoster"
android:text="Rihanna Love the way lie"
android:textColor="#040404"
android:textSize="15dip"
android:textStyle="bold"
android:typeface="sans" />
<TextView
android:id="@+id/FilmRequestOrder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/FilmRequestRating"
android:layout_toRightOf="@+id/FilmRequestPoster"
android:text="Order" />
</RelativeLayout>
单击“功能”
public static void ButtonClickFunction(Context context, Button button){
//Burası Ne işlem yapabileceğimizi gösteriyor.
//REQUESTABLE veya VOTABLE değerleri alabilir.
String action=(String)button.getTag(R.string.film_request_action);
String id=(String)button.getTag(R.string.film_request_id);
Log.d("debug", "String action="+action);
if (action.equalsIgnoreCase("VOTEABLE")) {
VoteFilm(context, button,id);
} else if (action.equalsIgnoreCase("REQUESTABLE")) {
RequestFilm(context, button, id);
}
}
public static void VoteFilm(Context context, final Button button, final String id){
final String callUrl=context.getString(R.string.api_url)+"?request=vote_film&user_id=1&id="+id;
Log.d("debug", "FilmRequestActivity->VoteFilm->callUrl:"+callUrl);
new Thread(new Runnable() {
@Override
public void run() {
try {
GeneralFunctions.getUrl(callUrl);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
button.post(new Runnable() {
@Override
public void run() {
button.setText("Oylanmış");
button.setEnabled(false);
}
});
}
}).start();
Toast.makeText(context, "Film Oylandı", Toast.LENGTH_SHORT).show();
}
public static void RequestFilm(Context context, final Button button,final String id){
final String callUrl=context.getString(R.string.api_url)+"?request=request_film&user_id=1&id="+id;
Log.d("debug", "FilmRequestActivity->RequestFilm->callUrl:"+callUrl);
new Thread(new Runnable() {
@Override
public void run() {
String jsonString;
final JSONObject jsonObject;
try {
jsonString = GeneralFunctions.getUrl(callUrl);
jsonObject=GeneralFunctions.StringToJSONObject(jsonString);
if (jsonObject!=null) {
button.post(new Runnable() {
@Override
public void run() {
try {
Log.d("debug","Inside Thread");
JSONObject data=(JSONObject) jsonObject.get("data");
String new_id=data.getString("id");
button.setTag(R.string.film_request_action,"VOTEABLE");
button.setTag(R.string.film_request_id,new_id);
button.setText("+Oyla");
button.setEnabled(true);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
答案 0 :(得分:2)
问题是,在致电ButtonClickFunction
时,您永远不会修改适配器的内容。这样滚动时,会保持保持状态,旧字符串将设置为按钮。我建议你更好地考虑你的设计。作为快速修复,您可以为Button设置另一个标记,在位置添加FilmRequest对象,例如:
final FilmRequest filmRequest = (FilmRequest)data.get(position);
String status = filmRequest.status;
boolean requested = filmRequest.requested;
boolean voted = filmRequest.voted;
然后,在ButtonClickFunction
内,检索此标记并相应地更改其status
答案 1 :(得分:0)
您没有正确使用ViewHolder模式。您必须创建一个ViewHolder并使用setTag和getTag来存储项目的状态:
if (convertView == null) {
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
答案 2 :(得分:0)
我是同一个问题,但我通过此代码解决
public class CustomizeListView extends ListActivity {
LayoutInflater inflater;
static int index = 0;
// AutoCompleteTextView autoCompleteTextView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_order);
inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, arrayList_Category);
dataAdapter
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
final CustomAdapter adapter = new CustomAdapter(this,
R.layout.activity_orderitem, arrayListItems);
setListAdapter(adapter);
}
private class CustomAdapter extends ArrayAdapter<HashMap<String, Object>>
implements OnItemSelectedListener {
boolean[] checkBoxState;
ViewHolder viewHolder;
public CustomAdapter(Context context, int textViewResourceId,
ArrayList<HashMap<String, Object>> arrayListItems) {
// let android do the initializing :)
super(context, textViewResourceId, arrayListItems);
checkBoxState = new boolean[arrayListItems.size()];
}
// class for caching the views in a row
private class ViewHolder {
CheckBox checkBox;
}
@Override
public View getView(final int position, View convertView,
ViewGroup parent) {
Log.d("getView", "getView");
if (convertView == null) {
convertView = inflater.inflate(R.layout.activity_orderitem,
null);
viewHolder = new ViewHolder();
// cache the views
convertView.setTag(viewHolder);
} else
viewHolder = (ViewHolder) convertView.getTag();
viewHolder.checkBox.setChecked(checkBoxState[position]);
viewHolder.checkBox.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (((CheckBox) v).isChecked()) {
checkBoxState[position] = true;
} else {
checkBoxState[position] = false;
}
}
});
return convertView;
}
}
}
答案 3 :(得分:0)
在我看来,您正在使用视图来存储其状态,因此当视图在滚动中被回收时,原始元素将丢失状态,甚至可以将状态分配给获取回收视图的其他元素。 尝试存储不在视图中但在适配器中的不同结构中的元素的状态。