mercredi 9 mars 2016

onBindViewHolder not displaying correct item in recyclerview

I'm using Recyclerview to populate a list with items from an SQLite database.

My problem is that i'm trying to apply logic so i dont show items marked as 'deleted'.

What happens instead is that the item is removed from the screen and the relevant database record is updated correctly but when i interact with the item view (scroll, reload or tap) it turns out that the item is still there.

Here are some photos to make things clearer:

Photo 1

This is how the list loads up, everything is normal and i have a toast set to go off when a list item is tapped. This one shows the pack id of 1920 for the top item, this is correct. Normal list

Photo 2

This photo shows the popup menu for the item with the delete option. When i tap this option the item disappears and i get a toast to confirm what pack id was marked as deleted. Show Menu

Photo 3 This image shows the problem i'm having. Although the correct item has gone when i tap on what is now pack id 1919 i get a toast for 1920. Furthermore when i reload this activity the item when 1920 should be can be any pack really. Problem list

The Activity

public class PacksActivity extends AppCompatActivity  implements DownloadManager.DownloadCallback {

private RecyclerView mRecyclerView;
private StaggeredGridLayoutManager mStaggeredLayoutManager;
private PackListAdapter mAdapter;
private static SQLiteHandler db;
public static final String PREFS_NAME = "loginPrefs";
public static final String PREFS_CHECKBOX = "returnedCheckable";
SwipeRefreshLayout mySwipeRefreshLayout;
DownloadManager downloadManager;
PopupMenu popupMenu;
SharedPreferences pref;
TextView packStatus;
LinearLayout placeHolder;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_packs);

    int spanCount = getResources().getInteger(R.integer.spanCount);

    mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);


    mStaggeredLayoutManager = new StaggeredGridLayoutManager(spanCount, StaggeredGridLayoutManager.VERTICAL);
    mRecyclerView.setLayoutManager(mStaggeredLayoutManager);
    db = new SQLiteHandler(this);
    mAdapter = new PackListAdapter(this);
    mySwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swiperefresh);
    mySwipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary);
    mRecyclerView.setAdapter(mAdapter);

    mAdapter.setOnItemClickListener(onItemClickListener);
    mAdapter.setOnItemLongClickListener(onItemLongClickListener);

    String first_name = db.getFromTable(this, DB.TABLE_LOGIN, DB.KEY_FIRST_NAME, null);
    String last_name = db.getFromTable(this, DB.TABLE_LOGIN, DB.KEY_LAST_NAME, null);

    setTitle(first_name + " " + last_name);
    /*
     * Sets up a SwipeRefreshLayout.OnRefreshListener that is invoked when the user
     * performs a swipe-to-refresh gesture.
     */
    mySwipeRefreshLayout.setOnRefreshListener(
            new SwipeRefreshLayout.OnRefreshListener() {
                @Override
                public void onRefresh() {
                    refreshPacks();
                }
            }
    );
}

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
    switch (item.getItemId())
    {
        case R.id.menu_logout:
            // Single menu item is selected do something
            // Ex: launching new activity/screen or show alert message
            pref = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
            pref.edit().clear().commit();

            Intent myIntent = new Intent(this, LoginActivity.class);
            startActivity(myIntent);
            return true;
        case R.id.menu_refresh:
            mySwipeRefreshLayout.setRefreshing(true);
            refreshPacks();
            return true;
        case R.id.returnCheckable:
            SharedPreferences pref = getSharedPreferences(PREFS_NAME,MODE_PRIVATE);
            boolean checked = pref.getBoolean(PREFS_CHECKBOX, true);

            if(checked == true){
                item.setChecked(false);
                pref.edit().putBoolean(PREFS_CHECKBOX, false).commit();
            }else{
                item.setChecked(true);
                pref.edit().putBoolean(PREFS_CHECKBOX, true).commit();
            }

            refreshActivity();

            return true;
        default:
            return super.onOptionsItemSelected(item);

    }

}

public void refreshActivity(){
    mAdapter.notifyDataSetChanged();
    /*Intent intent = getIntent();
    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
    finish();
    startActivity(intent);*/
}
public void refreshPacks(){

    URL url;
    try{
        url = new URL(getString(R.string.serverURL) + getString(R.string.getPacks));

        downloadManager = new DownloadManager(PacksActivity.this, PacksActivity.this);
        downloadManager.downloadPacks(url);

    }catch(MalformedURLException e){
        e.printStackTrace();
    }

}

// Initiating Menu XML file (menu.xml)
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    MenuInflater menuInflater = getMenuInflater();
    menuInflater.inflate(R.menu.packs_menu, menu);

    SharedPreferences pref = getSharedPreferences(PREFS_NAME,MODE_PRIVATE);
    boolean checked = pref.getBoolean(PREFS_CHECKBOX, true);

    menu.findItem(R.id.returnCheckable).setChecked(checked);

    return true;
}


@Override
public void onBackPressed(){
    super.onBackPressed();
    Intent intent = new Intent(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_HOME);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(intent);
    finish();
    System.exit(0);
}

@TargetApi(19)
public void createPopUpMenu(View v, final int position){
    TextView packStatus = (TextView) v.findViewById(R.id.packStatus);
    int version = Build.VERSION.SDK_INT;
    if (version >= 19) {
        popupMenu = new PopupMenu(this, packStatus, Gravity.END);
    }else{
        popupMenu = new PopupMenu(this, packStatus);
    }

    popupMenu.getMenuInflater().inflate(R.menu.pack_context_menu, popupMenu.getMenu());

    String dl = db.getFromTable(MyApplication.getAppContext(), DB.TABLE_PACKS, DB.KEY_DOWNLOADED, " WHERE " + DB.KEY_ID + "=" + position);
    String ps = db.getFromTable(MyApplication.getAppContext(), DB.TABLE_PACKS, DB.KEY_PACK_STATUS_ID, " WHERE " + DB.KEY_ID + "=" + position);

    boolean downloaded = Boolean.parseBoolean(dl);



    if(!downloaded) {
        popupMenu.getMenu().removeItem(R.id.pack_context_open);
        popupMenu.getMenu().removeItem(R.id.pack_context_submit);
        popupMenu.getMenu().removeItem(R.id.pack_context_sync);
    }else{
        popupMenu.getMenu().removeItem(R.id.pack_context_download);
    }

    try {
        int packStatusID = Integer.parseInt(ps);

        if (packStatusID == 6) {
            popupMenu.getMenu().removeItem(R.id.pack_context_submit);
        }
    }catch(NumberFormatException e){
        e.printStackTrace();
    }

    try {
        Field field = popupMenu.getClass().getDeclaredField("mPopup");
        field.setAccessible(true);
        Object menuPopupHelper = field.get(popupMenu);
        Class<?> cls = Class.forName("com.android.internal.view.menu.MenuPopupHelper");
        Method method = cls.getDeclaredMethod("setForceShowIcon", new Class[]{boolean.class});
        method.setAccessible(true);
        method.invoke(menuPopupHelper, new Object[]{true});
    } catch (Exception e) {
        e.printStackTrace();
    }
    popupMenu.show();


    popupMenu.setOnMenuItemClickListener(
            new PopupMenu.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {
                    int pos = position +1;
                    String pack_id = db.getFromTable(PacksActivity.this, DB.TABLE_PACKS, DB.KEY_PACK_ID, " WHERE " + DB.KEY_ID + "='" + pos + "'");

                    String elr = db.getFromTable(PacksActivity.this, DB.TABLE_ELR, DB.KEY_ELR, " WHERE " + DB.KEY_PACK_ID + "='" + pack_id + "'");
                    final String pack_client_no = db.getFromTable(PacksActivity.this, DB.TABLE_PACKS, DB.KEY_PACK_CLIENT_NO, " WHERE " + DB.KEY_ID + "='" + pos + "'");

                    String str = "SSOW No: " + pack_client_no + " " + elr;
                    switch (item.getItemId()) {
                        case R.id.pack_context_delete:
                            Toast.makeText(PacksActivity.this, "Delete - "+str, Toast.LENGTH_SHORT).show();
                            String[][] deleteValue = {
                                    {DB.KEY_DELETED, "1"}
                            };
                            db.update(DB.TABLE_PACKS, deleteValue, DB.KEY_PACK_ID + "=" + pack_id);
                            mAdapter.notifyItemRemoved(position);
                            //refreshActivity();
                            break;
                        case R.id.pack_context_sync:
                            Toast.makeText(PacksActivity.this, "Sync - "+str, Toast.LENGTH_SHORT).show();
                            break;
                        case R.id.pack_context_submit:
                            Toast.makeText(PacksActivity.this, "Submit - "+str, Toast.LENGTH_SHORT).show();
                            break;
                        case R.id.pack_context_download:
                            Toast.makeText(PacksActivity.this, "Download - "+str, Toast.LENGTH_SHORT).show();
                            break;
                        case R.id.pack_context_open:
                            Toast.makeText(PacksActivity.this, "Open - "+str, Toast.LENGTH_SHORT).show();
                            break;
                    }
                    return true;
                }
            });
}

PackListAdapter.OnItemClickListener onItemClickListener = new PackListAdapter.OnItemClickListener() {
    @Override
    public void onItemClick(View v, final int position) {
        int pos = position +1;
        String pack_id = db.getFromTable(PacksActivity.this, DB.TABLE_PACKS, DB.KEY_PACK_ID, " WHERE " + DB.KEY_ID + "='" + pos + "'");

        String elr = db.getFromTable(PacksActivity.this, DB.TABLE_ELR, DB.KEY_ELR, " WHERE " + DB.KEY_PACK_ID + "='" + pack_id + "'");
        final String pack_client_no = db.getFromTable(PacksActivity.this, DB.TABLE_PACKS, DB.KEY_PACK_CLIENT_NO, " WHERE " + DB.KEY_ID + "='" + pos + "'");

        Toast.makeText(PacksActivity.this, "SSOW No: " + pack_client_no + " " + elr, Toast.LENGTH_SHORT).show();
    }
};

PackListAdapter.OnItemLongClickListener onItemLongClickListener = new PackListAdapter.OnItemLongClickListener(){
    @Override
    public void onItemLongClick(View v, int position){
        createPopUpMenu(v, position);
    }
};

public void callback(DownloadManager.DownloadType downloadType) {
    mySwipeRefreshLayout.setRefreshing(false);
    mAdapter.notifyDataSetChanged();
}
}

The Adapter

public class PackListAdapter extends RecyclerView.Adapter<PackListAdapter.ViewHolder> {

Context mContext;
SQLiteHandler db;
OnItemClickListener mItemClickListener;
OnItemLongClickListener mItemLongClickListener;
public static final String PREFS_NAME = "loginPrefs";
public static final String PREFS_CHECKBOX = "returnedCheckable";
SharedPreferences pref;

// 2
public PackListAdapter(Context context) {
    this.mContext = context;
}

// 3
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener{
    public LinearLayout placeHolder;
    public LinearLayout placeNameHolder;
    public TextView placeName;
    public TextView packStatus;
    public ImageView placeImage;
    public ViewHolder(View itemView) {
        super(itemView);
        placeHolder = (LinearLayout) itemView.findViewById(R.id.mainHolder);
        placeName = (TextView) itemView.findViewById(R.id.placeName);
        packStatus = (TextView) itemView.findViewById(R.id.packStatus);
        placeNameHolder = (LinearLayout) itemView.findViewById(R.id.placeNameHolder);
        placeImage = (ImageView) itemView.findViewById(R.id.placeImage);
        packStatus.setOnClickListener(this);
        placeHolder.setOnClickListener(this);
        placeHolder.setOnLongClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if (mItemClickListener != null) {
            mItemClickListener.onItemClick(itemView, getAdapterPosition());
        }
    }

    @Override
    public boolean onLongClick(View v){
        if(mItemLongClickListener != null){
            mItemLongClickListener.onItemLongClick(itemView, getAdapterPosition());
        }
        return true;
    }
}

public interface OnItemClickListener {
    void onItemClick(View view, int position);
}

public interface OnItemLongClickListener{
    void onItemLongClick(View view, int position);
}

public void setOnItemClickListener(final OnItemClickListener mItemClickListener) {
    this.mItemClickListener = mItemClickListener;
}

public void setOnItemLongClickListener(final OnItemLongClickListener mItemLongClickListener){
    this.mItemLongClickListener = mItemLongClickListener;
}
// 1
@Override
public int getItemCount() {
    int val;
    if(db == null){
        db = new SQLiteHandler(mContext);
    }

    pref = mContext.getSharedPreferences(PREFS_NAME, mContext.MODE_PRIVATE);
    boolean checked = pref.getBoolean(PREFS_CHECKBOX, true);

    if(checked){
        val = db.getRowCount("*", DB.TABLE_PACKS, " WHERE " + DB.KEY_PACK_STATUS_ID + "!='6' AND " + DB.KEY_DELETED + "!='1'");
    }else{
        val = db.getRowCount("*", DB.TABLE_PACKS, " WHERE " + DB.KEY_DELETED + "!='1'");
    }
    Log.d("itemCount", val+""+checked);
    return val;
}

// 2
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_places, parent, false);
    return new ViewHolder(view);
}

// 3
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
    db = new SQLiteHandler(this.mContext);
    int pos = position +1;
    final String pack_id = db.getFromTable(mContext, DB.TABLE_PACKS, DB.KEY_PACK_ID, " WHERE " + DB.KEY_ID + "='" + pos + "'");


    Log.d("pid", pack_id+"");
    if(pack_id != null) {

        pref = mContext.getSharedPreferences(PREFS_NAME, mContext.MODE_PRIVATE);
        boolean checked = pref.getBoolean(PREFS_CHECKBOX, true);

        final String pack_status_id = db.getFromTable(mContext, DB.TABLE_PACKS, DB.KEY_PACK_STATUS_ID, " WHERE " + DB.KEY_ID + "='" + pos + "'");
        final String deleted = db.getFromTable(mContext, DB.TABLE_PACKS, DB.KEY_DELETED, " WHERE " + DB.KEY_ID + "='" + pos + "'");

        if((checked == true && Integer.parseInt(pack_status_id) == 6) || Integer.parseInt(deleted) == 1){
            Log.d("returned", "hide - " + deleted);
        }else{

            final String lat = db.getFromTable(mContext, DB.TABLE_PACKS, DB.KEY_PACK_AP_LAT, " WHERE " + DB.KEY_ID + "='" + pos + "'");
            final String lng = db.getFromTable(mContext, DB.TABLE_PACKS, DB.KEY_PACK_AP_LONG, " WHERE " + DB.KEY_ID + "='" + pos + "'");

            String elr = db.getFromTable(mContext, DB.TABLE_ELR, DB.KEY_ELR, " WHERE " + DB.KEY_PACK_ID + "='" + pack_id + "'");
            final String pack_client_no = db.getFromTable(mContext, DB.TABLE_PACKS, DB.KEY_PACK_CLIENT_NO, " WHERE " + DB.KEY_ID + "='" + pos + "'");

            holder.placeName.setText("SSOW No: " + pack_client_no + " " + elr);

            String[] pack_statusArr = mContext.getResources().getStringArray(R.array.pack_status);
            int[] pack_status_colorArr = mContext.getResources().getIntArray(R.array.pack_status_color);

            holder.packStatus.setText(pack_statusArr[Integer.parseInt(pack_status_id)]);
            holder.packStatus.setBackgroundColor(pack_status_colorArr[Integer.parseInt(pack_status_id)]);

            File folder = new File(Environment.getExternalStorageDirectory().getPath() + "/Android/data/" + mContext.getPackageName() + "/thumbs/");
            String filePath = folder + "/" + pack_id + pack_client_no + ".jpg";

            File file = new File(filePath);

            Picasso.with(mContext).load(file).into(holder.placeImage,new com.squareup.picasso.Callback() {
                @Override
                public void onSuccess() {

                }

                @Override
                public void onError() {
                    String Gurl = "http://ift.tt/IhGMtx" + lat+ "," + lng + "&zoom=17&size=600x300&markers=color:blue|" + lat + "," + lng + "&sensor=false";
                    Picasso.with(mContext).load(Gurl).into(holder.placeImage);
                    Picasso.with(mContext).load(Gurl).into(ServerDataHandler.getTarget(pack_id + pack_client_no, mContext));
                }
            });

            if(file.exists()){
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inPreferredConfig = Bitmap.Config.ARGB_8888;
                Bitmap photo = BitmapFactory.decodeFile(filePath, options);

                Palette.from(photo).generate(new Palette.PaletteAsyncListener() {
                    public void onGenerated(Palette p) {
                        int bgColor = p.getLightVibrantColor(getColor(mContext, android.R.color.black));
                        holder.placeNameHolder.setBackgroundColor(bgColor);
                    }
                });
            }else{
                holder.placeNameHolder.setBackgroundColor(getColor(mContext, R.color.babyBlue));
            }

        }


    }



}

public static final int getColor(Context context, int id) {
    final int version = Build.VERSION.SDK_INT;
    if (version >= 23) {
        return ContextCompat.getColor(context, id);
    } else {
        return context.getResources().getColor(id);
    }
}

}

Aucun commentaire:

Enregistrer un commentaire