将gridview替换为recyclerview

时间:2018-10-09 03:39:54

标签: android android-recyclerview

我已经搜索了论坛并找到了这个
How to replace gridView to RecyclerView 我对以上给出的答案不满意。
有没有一种更简单的方法,我可以在gridview中插入而不是重新创建新的适配器。

我一直在尝试遵循此Simple Android grid example using RecyclerView with GridLayoutManager (like the old GridView),但遇到这样的错误
多个dex文件定义了Landroid / support / design / widget / CoordinatorLayout $ ViewElevationComparator;

下面是我的代码。

MainActivity

public class Main3Activity extends AppCompatActivity implements MyRecyclerViewAdapter.ItemClickListener {

MyRecyclerViewAdapter adapter;

String[] files;

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

    //------------------------
    AssetManager am = getAssets();
    try {
        files  = am.list("img");

        // set up the RecyclerView
        RecyclerView recyclerView = findViewById(R.id.rv);
        int numberOfColumns = 3;
        recyclerView.setLayoutManager(new GridLayoutManager(this, numberOfColumns));
        adapter = new MyRecyclerViewAdapter(this);
        adapter.setClickListener(this);
        recyclerView.setAdapter(adapter);


    } catch (IOException e) {
        Toast.makeText(this, e.getLocalizedMessage(), Toast.LENGTH_SHORT);
    }

}

@Override
public void onItemClick(View view, int position) {
    Intent intent = new Intent(getApplicationContext(), PuzzleActivity.class);
    intent.putExtra("assetName", files[position % files.length]);
    startActivity(intent);
}

}

ImageAdapter

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

private String[] mData;
private LayoutInflater mInflater;
private ItemClickListener mClickListener;

private Context mContext;
private AssetManager am;
private String[] files;

// data is passed into the constructor
MyRecyclerViewAdapter(Context context) {
    this.mInflater = LayoutInflater.from(context);
    //this.mData = data;

    mContext = context;
    am = mContext.getAssets();
    try {
        mData  = am.list("img");
    } catch (IOException e) {
        e.printStackTrace();
    }

}

// inflates the cell layout from xml when needed
@Override
@NonNull
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = mInflater.inflate(R.layout.recyclerview_item, parent, false);
    return new ViewHolder(view);
}

// binds the data to the TextView in each cell
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    holder.myTextView.setText(mData[position]);
}

// total number of cells
@Override
public int getItemCount() {
    return mData.length;
}


// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    TextView myTextView;

    ViewHolder(View itemView) {
        super(itemView);
        myTextView = itemView.findViewById(R.id.info_text);
        itemView.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());

    }
}

// convenience method for getting data at click position
String getItem(int id) {
    return mData[id];
}

// allows clicks events to be caught
void setClickListener(ItemClickListener itemClickListener) {
    this.mClickListener = itemClickListener;
}

// parent activity will implement this method to respond to click events
public interface ItemClickListener {
    void onItemClick(View view, int position);
}


//---------------------------------------------------------------------
// create a new ImageView for each item referenced by the Adapter
public View getView(final int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
        convertView = layoutInflater.inflate(R.layout.grid_element, null);
    }

    final ImageView imageView = convertView.findViewById(R.id.gridImageview);
    imageView.setImageBitmap(null);
    // run image related code after the view was laid out
    imageView.post(new Runnable() {
        @Override
        public void run() {
            new AsyncTask<Void, Void, Void>() {
                private Bitmap bitmap;
                @Override
                protected Void doInBackground(Void... voids) {
                    bitmap = getPicFromAsset(imageView, files[position]);
                    return null;
                }

                @Override
                protected void onPostExecute(Void aVoid) {
                    super.onPostExecute(aVoid);
                    imageView.setImageBitmap(bitmap);
                }
            }.execute();
        }
    });

    return convertView;
}

private Bitmap getPicFromAsset(ImageView imageView, String assetName) {
    // Get the dimensions of the View
    int targetW = imageView.getWidth();
    int targetH = imageView.getHeight();

    if(targetW == 0 || targetH == 0) {
        // view has no dimensions set
        return null;
    }

    try {
        InputStream is = am.open("img/" + assetName);
        // Get the dimensions of the bitmap
        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
        bmOptions.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(is, new Rect(-1, -1, -1, -1), bmOptions);
        int photoW = bmOptions.outWidth;
        int photoH = bmOptions.outHeight;

        // Determine how much to scale down the image
        int scaleFactor = Math.min(photoW/targetW, photoH/targetH);

        is.reset();

        // Decode the image file into a Bitmap sized to fill the View
        bmOptions.inJustDecodeBounds = false;
        bmOptions.inSampleSize = scaleFactor;
        bmOptions.inPurgeable = true;

        return BitmapFactory.decodeStream(is, new Rect(-1, -1, -1, -1), bmOptions);
    } catch (IOException e) {
        e.printStackTrace();

        return null;
    }
}

}

问题:
1.如何进行这项工作?
2.错误是什么?

2 个答案:

答案 0 :(得分:1)

您的适配器如下所示:

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

private String[] mData;
private LayoutInflater mInflater;
private ItemClickListener mClickListener;

private Context mContext;
private AssetManager am;
private String[] files;

// data is passed into the constructor
MyRecyclerViewAdapter(Context context) {
    this.mInflater = LayoutInflater.from(context);
    //this.mData = data;

    mContext = context;
    am = mContext.getAssets();
    try {
        mData = am.list("img");
    } catch (IOException e) {
        e.printStackTrace();
    }

}

// inflates the cell layout from xml when needed
@Override
@NonNull
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = mInflater.inflate(R.layout.grid_element, parent, false);
    return new ViewHolder(view);
}

// binds the data to the TextView in each cell
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    //        holder.myTextView.setText(mData[position]);
    holder.imageView.setImageBitmap(null);
    // run image related code after the view was laid out
    holder.imageView.post(new Runnable() {
        @Override
        public void run() {
            new AsyncTask<Void, Void, Void>() {
                private Bitmap bitmap;

                @Override
                protected Void doInBackground(Void... voids) {
                    bitmap = getPicFromAsset(holder.imageView, files[position]);
                    return null;
                }

                @Override
                protected void onPostExecute(Void aVoid) {
                    super.onPostExecute(aVoid);
                    holder.imageView.setImageBitmap(bitmap);
                }
            }.execute();
        }
    });
}

// total number of cells
@Override
public int getItemCount() {
    return mData.length;
}


// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    //        TextView myTextView;
    ImageView imageView;

    ViewHolder(View itemView) {
        super(itemView);
    //            myTextView = itemView.findViewById(R.id.info_text);
        imageView = itemView.findViewById(R.id.gridImageview);
        itemView.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());

    }
}

// convenience method for getting data at click position
String getItem(int id) {
    return mData[id];
}

// allows clicks events to be caught
void setClickListener(ItemClickListener itemClickListener) {
    this.mClickListener = itemClickListener;
}

// parent activity will implement this method to respond to click events
public interface ItemClickListener {
    void onItemClick(View view, int position);
}

private Bitmap getPicFromAsset(ImageView imageView, String assetName) {
    // Get the dimensions of the View
    int targetW = imageView.getWidth();
    int targetH = imageView.getHeight();

    if (targetW == 0 || targetH == 0) {
        // view has no dimensions set
        return null;
    }

    try {
        InputStream is = am.open("img/" + assetName);
        // Get the dimensions of the bitmap
        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
        bmOptions.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(is, new Rect(-1, -1, -1, -1), bmOptions);
        int photoW = bmOptions.outWidth;
        int photoH = bmOptions.outHeight;

        // Determine how much to scale down the image
        int scaleFactor = Math.min(photoW / targetW, photoH / targetH);

        is.reset();

        // Decode the image file into a Bitmap sized to fill the View
        bmOptions.inJustDecodeBounds = false;
        bmOptions.inSampleSize = scaleFactor;
        bmOptions.inPurgeable = true;

        return BitmapFactory.decodeStream(is, new Rect(-1, -1, -1, -1), bmOptions);
    } catch (IOException e) {
        e.printStackTrace();

        return null;
    }
}
}

答案 1 :(得分:0)

我声明int column = 3,即创建多少列。 在您的活动代码中创建如下所示:

public class MyActivity extends Activity {
        private RecyclerView mRecyclerView;
        private RecyclerView.Adapter mAdapter;
        private RecyclerView.LayoutManager mLayoutManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.my_activity);
    mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);

    // use this setting to improve performance if you know that changes
    // in content do not change the layout size of the RecyclerView
    mRecyclerView.setHasFixedSize(true);

    // use a linear layout manager
    int column = 3;    

    mLayoutManager = reyclerView.setLayoutManager(new GridLayoutManager(context,column));
    mRecyclerView.setLayoutManager(mLayoutManager);

    // specify an adapter (see also next example)
    mAdapter = new MyAdapter(myDataset);
    mRecyclerView.setAdapter(mAdapter);
}

并创建一些适配器,如下所示:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
  private String[] mDataset;
  private Context mContext;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class MyViewHolder extends RecyclerView.ViewHolder {
    // each data item is just a string in this case
    public ImageView mImageView;
    public MyViewHolder(ImageView v) {
        super(v);
        mTextView = v;
    }
}

// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(String[] myDataset, Context context) {
    mDataset = myDataset;
    mContext = context;
}

// Create new views (invoked by the layout manager)
@Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
                                               int viewType) {
    // create a new view
    ImageView imageView = (ImageView) LayoutInflater.from(parent.getContext())
            .inflate(R.layout.my_text_view, parent, false);
    ...
    MyViewHolder vh = new MyViewHolder(imageView);
    return vh;
}

// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
    // - get element from your dataset at this position
    // - replace the contents of the view with that element
GlideApp
    .with(mContext)
    .load(mDataSet.getPosition(position).imageUrl)
    .centerCrop()
    .placeholder(R.drawable.loading_spinner)
    .into(holder.mImageView);

    holder.mImageView.setText(mDataset[position]);

}

// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
    return mDataset.length;
}
}

您可以了解有关recyclerView here的信息。 我是用户滑行加载图像。 this中有关滑行的文档。