【问题标题】:Is there any widget that replaces the deprecated Gallery widget是否有任何小部件可以替换已弃用的 Gallery 小部件
【发布时间】:2015-01-19 00:55:44
【问题描述】:

我需要在我的应用程序中实现某种水平 ListView,以便用户从第一个 ListView(类别)中选择一个项目后,第二个 ListView 显示与该选定项目相关的所有项目(类别中的产品)。

我原本打算使用 Gallery 小部件,但由于它已被弃用,我试图找到一个好的替代品,但没有成功。

这是我发现的:

  1. 使用ViewPager 的解决方案(参见CommonsWare 的回答):有点复杂,没有示例说明如何处理简单的click 事件。
  2. 使用实现 Horizontal ListView 的第三方库的解决方案:听起来不错,但不是官方小部件让我怀疑这是否是正确的方法。
  3. 使用第三方库的解决方案使用cover flow effect 实现了一个非常漂亮的画廊:与第二个解决方案相同的问题。

你看,主要问题是我已经开发了几个应用程序,不需要使用任何第三方库,除非真的有必要,否则我不想使用其中一个。

出于这个原因,我想问你们,如果你们知道任何结合的解决方案/方法:

  • 本地组件。
  • 易于使用。
  • 回收利用。

编辑:

按照@Ewoks 和@CommonsWare 的建议,我尝试了 RecyclerView,结果证明它正是我所需要的,并且没有我想象的那么复杂。

这是我使用的链接,以防有人发现它们有用:

通过对第二个链接的示例进行一些更改,我设法获得了我需要的两个画廊,其中第二个画廊列出了第一个画廊中选择的类别中的所有菜肴。

结果如下:

正如我所说,得到这个结果并不难,我只需要在LinearLayoutManager的构造函数中指明一个HORIZONTAL方向

mCategoryHorizontalManager=new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false);

另外我没有使用 Picasso,我使用了Ion,因为在我的项目中我还需要处理 HTTP 请求,而 Picasso 仅适用于图像。

好吧,我现在的问题不是如何显示图像,而是如何使单击的项目具有特殊的样式(框架、边框、背景颜色),这样可以非常清楚地选择了哪个项目.

到目前为止,我想我设法以某种方式改变了所选项目的样式,但我对此并不满意。您可以在上图中看到结果,其中所选项目具有不同的背景颜色(青色):

这是我的 RecyclerView 每个项目的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="10dp"
    android:gravity="center"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/picture_image_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp" />

    <TextView
        android:id="@+id/desc_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

这是我的适配器:

public class GalleryItemAdapter extends RecyclerView.Adapter<GalleryItemAdapter.ItemHolder>{

    /**
     * Click handler interface. RecyclerView does not have
     * its own built in like AdapterView do.
     */
    public interface OnItemClickListener{
        public void onItemClick(ItemHolder item, int position);
    }

    private List<GalleryObject> mItems;

    private OnItemClickListener mOnItemClickListener;
    private LayoutInflater mLayoutInflater;
    
    private View mSelectedView; 

    public GalleryItemAdapter(Context context,List<GalleryObject> picsList,int level){
        //...
        mSelectedView=null; //There's no selected item at first
    }

    @Override
    public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView=mLayoutInflater.inflate(R.layout.recycler_row, parent,false);

        return new ItemHolder(itemView,this);

    }

    @Override
    public void onBindViewHolder(ItemHolder holder, int position) {
        holder.setTituloTextView(mItems.get(position).getImageTitle());
        Ion.with(holder.getPicImageView())
                .placeholder(R.mipmap.owner_placeholder)
                .resize(mSize,mSize)
                .centerCrop()
                .error(R.mipmap.owner_error)
                .load(mItems.get(position).getImageUrl());

    }

    @Override
    public int getItemCount() {
        return mItems.size();
    }

    public OnItemClickListener getOnItemClickListener() {
        return this.mOnItemClickListener;
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        this.mOnItemClickListener = listener;
    }

    /* To highlight selected item*/

    public View getSelectedView() {
        return mSelectedView;
    }

    public void setSelectedView(View selectedView) {
        this.mSelectedView = selectedView;
    }

    /* Required implementation of ViewHolder to wrap item view */
    public static class ItemHolder extends RecyclerView.ViewHolder implements
        View.OnClickListener{
        private GalleryItemAdapter mParent;
        private TextView mTituloTextView;
        private ImageView mPicImageView;
        public ItemHolder(View itemView, GalleryItemAdapter parent) {
            super(itemView);
            itemView.setOnClickListener(this);

            mParent=parent;

            mTituloTextView= (TextView) itemView.findViewById(R.id.desc_text_view);
            mPicImageView= (ImageView) itemView.findViewById(R.id.picture_image_view);
        }

        public void setTituloTextView(CharSequence titulo) {
            this.mTituloTextView.setText(titulo);
        }

        public ImageView getPicImageView() {
            return mPicImageView;
        }
        public CharSequence getImageText(){
            return mTituloTextView.getText();
        }
        public int getGalleryLevel(){
            return mParent.mLevel;
        }

        @Override
        public void onClick(View v) {
            final OnItemClickListener listener=mParent.getOnItemClickListener();
            if(listener!=null){
                listener.onItemClick(this,getPosition());
            }
            setItemActivated(v);
        }
        public void setItemActivated(View v){
            if(mParent.getSelectedView()!=null){
               mParent.getSelectedView().setBackgroundColor(Color.TRANSPARENT);
            }
            v.setBackgroundColor(Color.CYAN);
            mParent.setSelectedView(v);
        }
    }
}

如您所见,每当用户点击我调用setItemActivated 的项目时,我使用getter getSelectedView() 检查mSelectedView 是否不为空(之前选择了项目),在这种情况下,我将背景颜色改回透明。

不管mSelectedView的值是多少,我把当前视图的背景颜色改成CYAN:

v.setBackgroundColor(Color.CYAN);

最后用当前选中的项目更新mSelectedView

mParent.setSelectedView(v);

这行得通,但结果很糟糕,因为它改变了整个视图的背景,而我认为只有图像应该以某种方式突出显示。

你知道我怎样才能更好地改变图片的风格吗?也许有一个开箱即用的解决方案可以突出显示我不知道的所选项目。

非常感谢。

【问题讨论】:

  • 为什么不直接使用框架库小部件?尽管它在 Jelly Bean 中已被弃用,但即使在 Lollipop 中也没有被删除。万一它会在未来的某个版本中被删除,您只需将其源代码复制到您的项目中即可。
  • 很可能是这种情况,这就是 deprecated 的意思。他们可以在任何下一个版本中删除它,而无需另行通知。除此之外,考虑到它的性能和 GC 调用,它的实现真的很糟糕......
  • 我同意 Ewoks 的观点,即 RecyclerView 将成为此的基础。

标签: android android-viewpager android-ui android-gallery android-recyclerview


【解决方案1】:

RecyclerView 和他的内置 LayoutManagers 我会推荐你​​ GridLayout 最适合画廊的目的。如果您不喜欢这样,您可以随时通过扩展 RecyclerView.LayoutManager 来实现自己的 LayoutManager

我希望这可以作为一些初始指南提供足够的帮助... ;)

附言我当然不会推荐 CoverFlow,因为所有其他提到的类都提供了更丰富的 API。此外,它的实现缺乏很多性能问题。

【讨论】:

  • 我听从了您的建议,使用 RecyclerView 模拟了一个图库,但是我对所选项目有问题。你认为你可以看看我的问题的 EDIT 部分吗?谢谢。
猜你喜欢
  • 2018-08-24
  • 1970-01-01
  • 1970-01-01
  • 2011-08-12
  • 2013-03-07
  • 1970-01-01
  • 1970-01-01
  • 2019-02-12
  • 2017-06-28
相关资源
最近更新 更多