简体   繁体   中英

Wrong remove listview item position using arraylist with custom baseadapter

I tried to remove the ListView item using ArrayList when I click item position. However, it always gets wrong removed item position. Why the item is deleted from the bottom? If I click anywhere in ListView , the position still removes from the item from the bottom. Anybody can help me in this problem?

This is how I fetch data from the database

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")));
}

I'm using fragment in onCreateView with setOnItemClickListener

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
        arrIdJob.remove(i);
        adapterListHome.notifyDataSetChanged();
    }
});

And this is my Adapter that extends 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;
       }
    }
}

Looks like you are using an ArrayList that holds the integer and you are trying to remove the items by the index of the item. The ArrayList.remove() function takes both the index and the element to be removed from the list. In your case, as they both are int , this should remove the element from your ArrayList by the index that is provided here - arrIdJob.remove(i); . Which is fine I think.

The problem that I see is your data structure and how you have kept your data in order to show them in the ListView . You have a lot of ArrayList s in your HomeFragment and removing the data from the arrIdJob actually requires the other ArrayList s to clean up themselves too. Because they all are being referenced and hence used in your adapter.

Hence, only removing the id from the arrIdJob should not suffice in your case, as you have to remove that specific item from the other lists too in order to remove the item completely from the list. Hence your implementation of the item click listener might look like the following.

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();
    }
});

Removing all those should completely remove the item from the list actually and you should get rid of any unusual behavior.

I would also suggest setting up your data in an object-oriented manner. That being said, I would rather create an object like the following.

public class CompanyAndJob {
    public int jobId; 
    public int companyName; 
    public int jobStr;
    public int qualification;
    // .... Other items
}

And then, I would create a List of CompanyAndJob object to be passed to the adapter via the constructor of the adapter. That would make the overall implementation a lot modular.

Also, if you are getting a list of objects that I suggested, you may have to modify the other parts of your adapter as well. For example, you need to modify the getItem as follows.

public CompanyAndJob getItem(int position) {
    return listOfCompanyAndJobs.get(position);
}

I hope you get the idea.

Replace getItem(int position) in your Adapter with

public Object getItem(int position) {
    return listData.get(position);
}

Also, make sure you're referring to the same list in your adapter and in your ItemClickListener .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM