单击RecyclerView项时,返回错误信息

时间:2017-12-28 21:54:54

标签: java android

很长的帖子,感谢花时间仔细阅读

我一直在努力解决这个问题。我有一个SQLiteDatabase,它存储鞋子的品牌名称,鞋子名称和鞋子的字节图像。我能够通过内容提供商将所有信息加载到recyclerview。但是当我尝试将信息加载到Recycler视图中的每个项目的详细信息时,详细信息活动会填充错误的信息,它会返回一个完全不同的条目,而不是我选择的条目。

我在许多YouTube视频中看到的解决方案都包含了我创建ArrayLists来存储信息的方法,但我发现使用我的SQLiteDatabase信息很难做到。

以下是我的课程...... 我的Closet.java类(使用我的getter方法)

<div *ngFor="let item of agendaData | async ">
{{ item.name }}
</div>

我的适配器类(CustomAdapter.java)

package com.example.android.myshoecloset;

import android.database.Cursor;
import android.os.Parcel;
import android.os.Parcelable;

/**
 * Created by man on 12/21/2017.
 */

public class Closet
{


    private static final String TAG = Closet.class.getSimpleName();

    //Brand name
    private final String brandName;
    //Shoe Name
    private final String shoeName;
    //Image of the shoe
    private final String shoeImage;


    public Closet(String brandName, String shoeName, String shoeImage)
    {
        this.brandName = brandName;
        this.shoeName  = shoeName;
        this.shoeImage = shoeImage;
    }

    public Closet(Cursor cursor)
    {
        this.brandName = null;
        this.shoeName = null;
        this.shoeImage = null;
    }

    public String getShoeImageName()
    {
        return shoeImage;
    }

    public String getBrandName()
    {
        return brandName;
    }

    public String getShoeName()
    {
        return shoeName;
    }

}

My ClosetFragment,它将加载器上的信息加载到片段recyclelerview。

package com.example.android.myshoecloset.data;
/*Assume appropriate imports*/

/**
 * Created by man on 11/23/2017.
 */

public class CustomAdapter  extends RecyclerView.Adapter<CustomAdapter.TaskHolder> {

    private Cursor mCursor;
    private Context mContext;

    public static String shoeName;
    public static String brandName;
    public static byte[] byteArray;

    public CustomAdapter(Context mContext) {
        this.mContext = mContext;
    }

    public CustomAdapter()
    {
        mContext = null;
    }





    /* ViewHolder for each task item */
    public class TaskHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public TextView shoeBrandName;
        public TextView shoeName;
        public ImageView shoeImage;
        public LinearLayout linearLayout;

        public TaskHolder(final View itemView) {
            super(itemView);
            itemView.setOnClickListener(this);
            shoeBrandName = (TextView) itemView.findViewById(R.id.textBrandName);
            shoeImage = (ImageView) itemView.findViewById(R.id.shoeImage);
            shoeName = (TextView) itemView.findViewById(R.id.textShoeName);
            linearLayout = (LinearLayout) itemView.findViewById(R.id.linear_closet);
        }

        @Override
        public void onClick(View v) {
            Intent i = new Intent(v.getContext(), ShoeDetailActivity.class);
            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            v.getContext().startActivity(i);
        }


    }

    @Override
    public TaskHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        View itemView = inflater
                .inflate(R.layout.text_row_item, parent, false);
        return new TaskHolder(itemView);
    }

    @Override
    public void onBindViewHolder(TaskHolder holder, int position) {


        int idIndex = mCursor.getColumnIndex(DatabaseContract.ShoeColumns._ID);
        int imgValue = mCursor.getColumnIndex(DatabaseContract.ShoeColumns.SHOE_IMAGE);
        int shoeBrandName = mCursor.getColumnIndex(DatabaseContract.ShoeColumns.SHOE_BRAND);
        int shoeName = mCursor.getColumnIndex(DatabaseContract.ShoeColumns.SHOE_NAME);

        mCursor.moveToPosition(position);



        final int id = mCursor.getInt(idIndex);
        byte[] shoeImg = mCursor.getBlob(imgValue);
        String brandNameStr = mCursor.getString(shoeBrandName);
        String shoeNameStr = mCursor.getString(shoeName);

        Bitmap bmp = BitmapFactory.decodeByteArray(shoeImg, 0, shoeImg.length);

        holder.itemView.setTag(id);
        holder.shoeImage.setImageBitmap(Bitmap.createScaledBitmap(bmp, 100, 100, false));
        holder.shoeBrandName.setText(brandNameStr);
        holder.shoeName.setText(shoeNameStr);

        holder.getAdapterPosition();


        CustomAdapter.shoeName = shoeNameStr;
        CustomAdapter.brandName = brandNameStr;
        CustomAdapter.byteArray = mCursor.getBlob(imgValue);
    }

    @Override
    public int getItemCount() {
        return (mCursor != null) ? mCursor.getCount() : 0;
    }


    public void swapCursor(Cursor cursor) {
        if (mCursor != null) {
            mCursor.close();
        }
        mCursor = cursor;
        notifyDataSetChanged();
    }
}

最后这是我的DetailsActivity(当点击了recyclerview项目时,这就是点击将带你去的地方)

package com.example.android.myshoecloset;

/*Assume appropriate imports*/

public class ClosetFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
    private static final String TAG = "ClosetFragment";

    protected RecyclerView mRecyclerView;
    protected CustomAdapter mAdapter;
    private static final int CUSTOM_LOADER_ID = 0;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_closet, container, false);
        rootView.setTag(TAG);

        mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getApplicationContext()));

        mAdapter = new CustomAdapter(getActivity().getApplicationContext());
        mRecyclerView.setAdapter(mAdapter);

        getActivity().getSupportLoaderManager().initLoader(CUSTOM_LOADER_ID, null, this);

        return rootView;
    }

    @Override
    public void onResume()
    {
        super.onResume();
        getActivity().getSupportLoaderManager().restartLoader(CUSTOM_LOADER_ID, null, this);    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, final Bundle loaderArgs) {
                return new AsyncTaskLoader<Cursor>(getActivity().getApplicationContext()) {
            Cursor mTaskData = null;

            @Override
            protected void onStartLoading()
            {
                if(mTaskData != null)
                {
                    deliverResult(mTaskData);
                }
                else
                {
                    forceLoad();
                }
            }

            public Cursor loadInBackground()
            {
                try
                {
                    return getActivity().getApplicationContext().getContentResolver().query(DatabaseContract.CONTENT_URI,
                            null,
                            null,
                            null,
                            null);

                } catch(Exception e)
                {
                    Log.e("", "Failed to asynchronously load data.");
                    e.printStackTrace();
                    return null;
                }
            }

            public void deliverResult(Cursor data)
            {
                mTaskData = data;
                super.deliverResult(data);
            }
        };
    }


    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data)
    {
        mAdapter.swapCursor(data);
    }
    @Override
    public void onLoaderReset(Loader<Cursor> loader)
    {
        mAdapter.swapCursor(null);
    }

}

谢谢!

1 个答案:

答案 0 :(得分:0)

据我所知,您的代码的相关部分是您的视图持有者中的onClick方法:

@Override
public void onClick(View v) {
    Intent i = new Intent(v.getContext(), ShoeDetailActivity.class);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    v.getContext().startActivity(i);
}

详情活动中的onCreate方法:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    byte[] b = getIntent().getByteArrayExtra("ImageBit");
    ...
    brandShoe.setText(getIntent().getStringExtra("ShoeName"));
    nameShoe.setText(getIntent().getStringExtra("BrandName"));
}

在细节活动中,您试图从意图附加信息中提取信息......但您从未提供过该信息。向观看者提供此信息需要重新考虑如何实现视图持有者本身。

我相信你应该能够使用viewholder的“适配器位置”在点击时从光标中获取必要的信息。也许是这样的:

@Override
public void onClick(View v) {
    int position = getAdapterPosition();
    mCursor.moveToPosition(position);

    Intent i = new Intent(v.getContext(), ShoeDetailActivity.class);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    int imgValue = mCursor.getColumnIndex(DatabaseContract.ShoeColumns.SHOE_IMAGE);
    int shoeBrandName = mCursor.getColumnIndex(DatabaseContract.ShoeColumns.SHOE_BRAND);
    int shoeName = mCursor.getColumnIndex(DatabaseContract.ShoeColumns.SHOE_NAME);

    i.putExtra("ImageBit", mCursor.getBlob(imgValue));
    i.putExtra("ShoeName", mCursor.getString(shoeBrandName));
    i.putExtra("BrandName", mCursor.getString(shoeName));

    v.getContext().startActivity(i);
}

(请注意,"ShoeName""BrandName"似乎已被交换,但它们也会在您的详细信息活动中进行交换,因此我将其留给了他们。)

如果此getAdapterPosition() + mCursor方法不适合您,您始终可以在绑定时将必要信息传递给视图持有者,并在绑定时更新onClick()方法

如果这对您有用,请告诉我。如果没有,我们可以尝试从这里弄明白。