私は Android で個人的なプロジェクトに取り組んでおり、ListView を使用するアクティビティに関して奇妙な状況に遭遇しました。問題の基本は、アイテムのリストがあり、それぞれに編集と削除の 2 つのボタンがあることです。現在、機能的には機能する [削除] ボタンの実装に取り組んでいますが、ListView が正しく更新されません。代わりに、削除されたばかりのものをリストの一番上に置きます。もちろん、そのアクティビティに移動するたびに更新されます。
現在、カスタム BaseAdapter 内で [削除] ボタンが検出されており、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
}
}
編集: ソリューションには、Adam が提供したインフレーションの説明が含まれていましたが、dpList の完全な再作成が必要でした。
dpList = db.allDataThisMonth();
Anupが提案した。