我一直在研究Android中的個人項目,並且遇到了關於使用ListView的Activity的奇怪情況。問題的基礎是我有一個項目列表,每個項目有2個按鈕,編輯和刪除。現在我正在執行刪除按鈕,它可以在功能上工作,但不會正確更新ListView。相反,它會將剛刪除的內容放在列表的頂部。無論什麼時候我轉向這個活動,它當然都會刷新。在OnClickListener裏面刷新Android ListView數據
現在在自定義BaseAdapter中檢測到Delete按鈕,當我調用notifyDataSetChanged時,上述情況發生,而不是刪除現在已刪除的項目。我該如何正確更新適配器類中的列表?
我意識到有關於此的一些問題,但我沒有能夠整合它們,我認爲可能工作的解決方案並不能真正解釋它們是如何工作的;我正在使用這個項目來更多地瞭解Android應用程序的開發,所以我希望有一些解釋層次的答案,當然,任何幫助當然是讚賞! 謝謝!
下面是相關的代碼。請注意,這是一個未完成的項目,所以它裏面有一些未使用/不完整的東西。請忽略這些。
EditItemsActivity:
package com.example.mybudget;
import java.util.List;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
public class EditItemsActivity extends Activity implements OnGestureListener{
private DatabaseHandler db;
private List<DataPoint> dpList;
private EditItemsAdapter adapter;
private ListView lv;
private GestureDetector gestureDetector;
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_items);
// Show the Up button in the action bar.
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
getActionBar().setDisplayHomeAsUpEnabled(true);
db = new DatabaseHandler(this);
dpList = db.allDataThisMonth();
lv = (ListView) findViewById(R.id.edititems);
adapter = new EditItemsAdapter(this, R.id.edititems, dpList);
lv.setAdapter(adapter);
gestureDetector = new GestureDetector(getBaseContext(), this);
// buttonDelete.setVisibility(View.GONE);
}
public void refreshList()
{
adapter.notifyDataSetChanged();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_edit_items, menu);
return true;
}
@Override
public boolean onDown(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
public void onDelete()
{
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY)
{
// Log.d("Swipe", "" + velocityX + ", " + velocityY);
// if(velocityX > 200 && velocityY < 50 && velocityY > -50)
// {
// buttonEdit.setVisibility(View.GONE);
// buttonDelete.setVisibility(View.VISIBLE);
// }
// else if(velocityX < -200 && velocityY < 50 && velocityY > -50)
// {
// buttonDelete.setVisibility(View.GONE);
// buttonEdit.setVisibility(View.VISIBLE);
// }
return false;
}
@Override
public void onLongPress(MotionEvent e) {
// TODO Auto-generated method stub
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onShowPress(MotionEvent e) {
// TODO Auto-generated method stub
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
}
而這裏的適配器類:
package com.example.mybudget;
import java.text.NumberFormat;
import java.util.List;
import android.app.Activity;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;
public class EditItemsAdapter extends BaseAdapter implements OnClickListener{
private List<DataPoint> dpList;
private Activity activity;
private DatabaseHandler db;
public EditItemsAdapter(Activity a)
{
activity = a;
}
public EditItemsAdapter(Activity a, int textViewResourceId, List<DataPoint> dpList)
{
super();
this.dpList = dpList;
activity = a;
db = new DatabaseHandler(activity);
}
public static class ViewHolder
{
public TextView item1;
public TextView item2;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View v = convertView;
//ViewHolder holder;
NumberFormat format = NumberFormat.getCurrencyInstance();
if (v == null)
{
// LayoutInflater vi =
// (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LayoutInflater vi = activity.getLayoutInflater();
v = vi.inflate(R.layout.edit_grid_items, null);
// holder = new ViewHolder();
// holder.item1 = (TextView) v.findViewById(R.id.edit_item_name);
// holder.item2 = (TextView) v.findViewById(R.id.edit_item_cost);
// v.setTag(holder);
TextView tv1 = (TextView)v.findViewById(R.id.edit_item_name);
TextView tv2 = (TextView)v.findViewById(R.id.edit_item_cost);
Button edit = (Button)v.findViewById(R.id.edit_item_button);
Button delete = (Button)v.findViewById(R.id.delete_item_button);
final DataPoint dp = dpList.get(position);
tv1.setText(dp.getName());
tv2.setText(Float.toString(dp.getCost()));
delete.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
db.deleteRowByKey(dp);
((EditItemsActivity) activity).refreshList();
}
});
}
// else
// holder = (ViewHolder)v.getTag();
// if(dp != null)
// {
// holder.item1.setText(dp.getName());
// holder.item2.setText(format.format(dp.getCost()));
// }
return v;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return dpList.size();
}
@Override
public DataPoint getItem(int position) {
// TODO Auto-generated method stub
return dpList.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return dpList.size();
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
編輯: 該解決方案所涉及的通貨膨脹的解釋,亞當提供,但需要dpList的完整覆育的
dpList = db.allDataThisMonth();
那個建議特德。
感謝您對通貨膨脹的解釋!事實證明,這是問題的核心,儘管由於某種原因,我不得不完全重新填充列表(使用remove的解決方案由於某種原因而不起作用)。我將這個標記爲解決方案,因爲我不明白的主要問題是通貨膨脹,因爲我已經試圖在沒有這種改變的情況下重新填充名單。 – Mike
不用擔心!起初我也遇到了一些麻煩。至於你爲什麼不能從列表中刪除,如果'DataPoint'是一個自定義類,你需要實現'equals'和'hashCode'方法來使用'List.remove'。如果你使用Eclipse,這很容易:打開DataPoint類並右鍵單擊源窗口 - >源代碼 - >生成hashCode()和equals()。 Android的工作室是類似的:右源窗口 - >生成 - > equals()和hashCode() 希望幫助! –