使用带有自定义 baseadapter 的 arraylist 错误地删除列表视图项目位置
Wrong remove listview item position using arraylist with custom baseadapter
我试图在单击项目位置时使用 ArrayList
删除 ListView
项目。但是,它总是得到错误的删除项目位置。为什么从底部删除该项目?如果我单击 ListView
中的任意位置,该位置仍会从底部的项目中移除。有人可以帮我解决这个问题吗?
这是我从数据库中获取数据的方式
public static ArrayList<Integer> arrIdJob = new ArrayList<Integer>();
myJSON = json.getJSONArray(TAG_record);
for (int i = 0; i < myJSON.length(); i++) {
JSONObject c = myJSON.getJSONObject(i);
arrIdJob.add(Integer.parseInt(c.getString("id_jobpost")));
}
我在 onCreateView
和 setOnItemClickListener
中使用片段
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
arrIdJob.remove(i);
adapterListHome.notifyDataSetChanged();
}
});
这是我的 Adapter
扩展 BaseAdapter
public class AdapterListHome extends BaseAdapter {
private Activity activity;
private ArrayList<CustomRowClass> listData;
private LayoutInflater layoutInflater;
private Context context;
public AdapterListHome(Context context, ArrayList<CustomRowClass> listData) {
this.listData = listData;
layoutInflater = LayoutInflater.from(context);
this.context = context;
}
public AdapterListHome(Activity act) {
this.activity = act;
}
public int getCount() {
return HomeFragment.arrIdJob.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
@Override
public int getViewTypeCount() {
return getCount();
}
@Override
public int getItemViewType(int position) {
return position;
}
@SuppressLint("SetTextI18n")
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null){
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.desain_view, null);
holder = new ViewHolder();
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tvJobTitle = (TextView) convertView.findViewById(R.id.tv_jobtitile);
holder.tvCompanyName = (TextView) convertView.findViewById(R.id.tv_companyname);
holder.tvState = (TextView) convertView.findViewById(R.id.tv_state);
holder.tvSalary = (TextView) convertView.findViewById(R.id.tv_minsal);
//for key
holder.keyIdUser = (TextView) convertView.findViewById(R.id.key_iduser);
holder.keyIdJob = (TextView) convertView.findViewById(R.id.key_idjob);
holder.keyIdCompany = (TextView) convertView.findViewById(R.id.key_idcompany);
holder.keyQualification = (TextView) convertView.findViewById(R.id.key_qualification);
holder.keyDesc = (TextView) convertView.findViewById(R.id.key_desc);
//set
holder.tvJobTitle.setText(HomeFragment.arrJobTitle.get(position));
holder.tvCompanyName.setText(HomeFragment.arrCompanyName.get(position));
holder.tvState.setText(HomeFragment.arrState.get(position));
holder.tvSalary.setText(toRupiah(HomeFragment.arrMinSal.get(position))+" - "+toRupiah(HomeFragment.arrMaxSal.get(position)));
//set for key
holder.keyIdJob.setText(HomeFragment.arrIdJobStr.get(position));
holder.keyIdCompany.setText(HomeFragment.arrIdCompany.get(position));
holder.keyQualification.setText(HomeFragment.arrQualification.get(position));
holder.keyDesc.setText(HomeFragment.arrDesc.get(position));
// Picasso.get().load(Config.PATH_URL_IMG_CAT+ ListMenuActivity.IMAGE.get(position)).into(holder.imgThumb);
return convertView;
}
static class ViewHolder {
TextView tvJobTitle, tvCompanyName, tvState, tvSalary;
TextView keyIdUser, keyIdJob, keyIdCompany, keyQualification, keyDesc;
String data;
//ImageView imgThumb;
}
private String toRupiah(String nominal){
String hasil = "";
DecimalFormat toRupiah = (DecimalFormat) DecimalFormat.getCurrencyInstance();
DecimalFormatSymbols formatAngka = new DecimalFormatSymbols();
formatAngka.setCurrencySymbol("Rp. ");
formatAngka.setMonetaryDecimalSeparator(',');
toRupiah.setDecimalFormatSymbols(formatAngka);
hasil = toRupiah.format(Double.valueOf(nominal));
return hasil;
}
}
}
将适配器中的 getItem(int position)
替换为
public Object getItem(int position) {
return listData.get(position);
}
此外,请确保您在适配器和 ItemClickListener
中指的是同一个列表。
看起来您正在使用保存整数的 ArrayList
,并且您正试图通过项目的索引删除项目。 ArrayList.remove()
函数将 index
和 element
从列表中删除。在您的情况下,因为它们都是 int
,这应该通过此处提供的索引从您的 ArrayList
中删除元素 - arrIdJob.remove(i);
。我认为这很好。
我看到的问题是您的数据结构以及您如何保存数据以便在 ListView
中显示它们。您的 HomeFragment
中有很多 ArrayList
,从 arrIdJob
中删除数据实际上需要其他 ArrayList
也自行清理。因为它们都被引用并因此在您的适配器中使用。
因此,仅从 arrIdJob
中删除 id 在您的情况下应该是不够的,因为您还必须从其他列表中删除该特定项目才能从列表中完全删除该项目。因此,您对项目点击侦听器的实现可能如下所示。
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
arrIdJob.remove(i);
// Clear the other lists!
arrJobTitle.remove(i);
arrCompanyName.remove(i);
arrState.remove(i);
arrMinSal.remove(i);
arrIdJobStr.remove(i);
arrQualification.remove(i);
arrIdCompany.remove(i);
arrDesc.remove(i);
adapterListHome.notifyDataSetChanged();
}
});
删除所有这些实际上应该从列表中完全删除该项目,并且您应该摆脱任何异常行为。
我还建议以面向对象的方式设置数据。话虽如此,我宁愿创建一个如下所示的对象。
public class CompanyAndJob {
public int jobId;
public int companyName;
public int jobStr;
public int qualification;
// .... Other items
}
然后,我将创建一个 List
of CompanyAndJob
对象,通过适配器的构造函数传递给适配器。这将使整体实现更加模块化。
此外,如果您获得了我建议的对象列表,您可能还需要修改适配器的其他部分。例如,您需要修改 getItem
如下。
public CompanyAndJob getItem(int position) {
return listOfCompanyAndJobs.get(position);
}
我希望你明白了。
我试图在单击项目位置时使用 ArrayList
删除 ListView
项目。但是,它总是得到错误的删除项目位置。为什么从底部删除该项目?如果我单击 ListView
中的任意位置,该位置仍会从底部的项目中移除。有人可以帮我解决这个问题吗?
这是我从数据库中获取数据的方式
public static ArrayList<Integer> arrIdJob = new ArrayList<Integer>();
myJSON = json.getJSONArray(TAG_record);
for (int i = 0; i < myJSON.length(); i++) {
JSONObject c = myJSON.getJSONObject(i);
arrIdJob.add(Integer.parseInt(c.getString("id_jobpost")));
}
我在 onCreateView
和 setOnItemClickListener
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
arrIdJob.remove(i);
adapterListHome.notifyDataSetChanged();
}
});
这是我的 Adapter
扩展 BaseAdapter
public class AdapterListHome extends BaseAdapter {
private Activity activity;
private ArrayList<CustomRowClass> listData;
private LayoutInflater layoutInflater;
private Context context;
public AdapterListHome(Context context, ArrayList<CustomRowClass> listData) {
this.listData = listData;
layoutInflater = LayoutInflater.from(context);
this.context = context;
}
public AdapterListHome(Activity act) {
this.activity = act;
}
public int getCount() {
return HomeFragment.arrIdJob.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
@Override
public int getViewTypeCount() {
return getCount();
}
@Override
public int getItemViewType(int position) {
return position;
}
@SuppressLint("SetTextI18n")
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null){
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.desain_view, null);
holder = new ViewHolder();
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tvJobTitle = (TextView) convertView.findViewById(R.id.tv_jobtitile);
holder.tvCompanyName = (TextView) convertView.findViewById(R.id.tv_companyname);
holder.tvState = (TextView) convertView.findViewById(R.id.tv_state);
holder.tvSalary = (TextView) convertView.findViewById(R.id.tv_minsal);
//for key
holder.keyIdUser = (TextView) convertView.findViewById(R.id.key_iduser);
holder.keyIdJob = (TextView) convertView.findViewById(R.id.key_idjob);
holder.keyIdCompany = (TextView) convertView.findViewById(R.id.key_idcompany);
holder.keyQualification = (TextView) convertView.findViewById(R.id.key_qualification);
holder.keyDesc = (TextView) convertView.findViewById(R.id.key_desc);
//set
holder.tvJobTitle.setText(HomeFragment.arrJobTitle.get(position));
holder.tvCompanyName.setText(HomeFragment.arrCompanyName.get(position));
holder.tvState.setText(HomeFragment.arrState.get(position));
holder.tvSalary.setText(toRupiah(HomeFragment.arrMinSal.get(position))+" - "+toRupiah(HomeFragment.arrMaxSal.get(position)));
//set for key
holder.keyIdJob.setText(HomeFragment.arrIdJobStr.get(position));
holder.keyIdCompany.setText(HomeFragment.arrIdCompany.get(position));
holder.keyQualification.setText(HomeFragment.arrQualification.get(position));
holder.keyDesc.setText(HomeFragment.arrDesc.get(position));
// Picasso.get().load(Config.PATH_URL_IMG_CAT+ ListMenuActivity.IMAGE.get(position)).into(holder.imgThumb);
return convertView;
}
static class ViewHolder {
TextView tvJobTitle, tvCompanyName, tvState, tvSalary;
TextView keyIdUser, keyIdJob, keyIdCompany, keyQualification, keyDesc;
String data;
//ImageView imgThumb;
}
private String toRupiah(String nominal){
String hasil = "";
DecimalFormat toRupiah = (DecimalFormat) DecimalFormat.getCurrencyInstance();
DecimalFormatSymbols formatAngka = new DecimalFormatSymbols();
formatAngka.setCurrencySymbol("Rp. ");
formatAngka.setMonetaryDecimalSeparator(',');
toRupiah.setDecimalFormatSymbols(formatAngka);
hasil = toRupiah.format(Double.valueOf(nominal));
return hasil;
}
}
}
将适配器中的 getItem(int position)
替换为
public Object getItem(int position) {
return listData.get(position);
}
此外,请确保您在适配器和 ItemClickListener
中指的是同一个列表。
看起来您正在使用保存整数的 ArrayList
,并且您正试图通过项目的索引删除项目。 ArrayList.remove()
函数将 index
和 element
从列表中删除。在您的情况下,因为它们都是 int
,这应该通过此处提供的索引从您的 ArrayList
中删除元素 - arrIdJob.remove(i);
。我认为这很好。
我看到的问题是您的数据结构以及您如何保存数据以便在 ListView
中显示它们。您的 HomeFragment
中有很多 ArrayList
,从 arrIdJob
中删除数据实际上需要其他 ArrayList
也自行清理。因为它们都被引用并因此在您的适配器中使用。
因此,仅从 arrIdJob
中删除 id 在您的情况下应该是不够的,因为您还必须从其他列表中删除该特定项目才能从列表中完全删除该项目。因此,您对项目点击侦听器的实现可能如下所示。
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
arrIdJob.remove(i);
// Clear the other lists!
arrJobTitle.remove(i);
arrCompanyName.remove(i);
arrState.remove(i);
arrMinSal.remove(i);
arrIdJobStr.remove(i);
arrQualification.remove(i);
arrIdCompany.remove(i);
arrDesc.remove(i);
adapterListHome.notifyDataSetChanged();
}
});
删除所有这些实际上应该从列表中完全删除该项目,并且您应该摆脱任何异常行为。
我还建议以面向对象的方式设置数据。话虽如此,我宁愿创建一个如下所示的对象。
public class CompanyAndJob {
public int jobId;
public int companyName;
public int jobStr;
public int qualification;
// .... Other items
}
然后,我将创建一个 List
of CompanyAndJob
对象,通过适配器的构造函数传递给适配器。这将使整体实现更加模块化。
此外,如果您获得了我建议的对象列表,您可能还需要修改适配器的其他部分。例如,您需要修改 getItem
如下。
public CompanyAndJob getItem(int position) {
return listOfCompanyAndJobs.get(position);
}
我希望你明白了。