gpt4 book ai didi

android - 刷新 OnClickListener 中的 Android ListView 数据

转载 作者:太空狗 更新时间:2023-10-29 16:41:38 26 4
gpt4 key购买 nike

我一直在 Android 中从事个人项目,遇到了一个关于使用 ListView 的 Activity 的奇怪情况。问题的基础是我有一个项目列表,每个项目都有 2 个按钮,编辑和删除。现在我正在努力实现删除按钮,它可以正常工作,但不能正确更新 ListView。相反,它将刚刚删除的内容放在列表的顶部。每当我重新导航到该 Activity 时,它当然会刷新。

现在在自定义 BaseAdapter 中检测到删除按钮,当我调用 notifyDataSetChanged 时,会发生上述情况,而不是删除现在已删除的项目。如何正确更新适配器类中的列表?

我意识到有一些关于此的问题,但我无法整合它们,我认为可能有效的解决方案并没有真正解释它们是如何工作的;我正在使用这个项目来更多地了解 Android 应用程序开发,所以我更喜欢有一定程度解释的答案,尽管当然感谢任何帮助!谢谢!

这是相关代码。请注意,这是一个未完成的项目,因此其中有一些未使用/未完成的东西。请忽略这些。

编辑项目 Activity :

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 建议的。

最佳答案

在适配器的 getView 方法中,您正在检查 if (convertView == null) 并且如果它为 null,则您正在膨胀一个新 View 。如果它为 null,则您只是返回提供的非 null View 。

提供给 getView 方法的 convertView 是一个已经显示的缓存 View 。你应该重新使用它(如果它是一个有效的 View - 你的列表中可能有多个不同的 View ),而不是膨胀一个新的。您忘记为相应的位置更新它的内容。

那么,如何解决呢?只需在通货膨胀后关闭您的if (v == null):

if (v == null)
{
LayoutInflater vi = activity.getLayoutInflater();
v = vi.inflate(R.layout.edit_grid_items, null);
}

编辑:正如 Anup 指出的那样,您还需要更新您的 dpList 变量,否则它将继续为给定位置返回相同的值。您可以在点击监听器中执行此操作:

delete.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
db.deleteRowByKey(dp);
dpList.remove((Integer)v.getTag());
((EditItemsActivity) activity).refreshList();

}
});
// Required so we know which index to remove from our dpList.
delete.setTag(position);

关于android - 刷新 OnClickListener 中的 Android ListView 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16849906/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com