是否有任何小部件可以替代已弃用的 Gallery 小部件
Is there any widget that replaces the deprecated Gallery widget
我需要在我的应用程序中实现某种水平 ListView,以便在用户从第一个 ListView(类别)中选择一个项目后,第二个 ListView 显示与该所选项目相关的所有项目(类别中的产品) ).
我打算使用 Gallery
小部件,但由于它已被弃用,我试图找到一个好的替代品,但没有成功。
这是我发现的:
- 使用 ViewPager 的解决方案(参见 CommonsWare 的回答):有点复杂,没有关于如何处理简单
click
事件的示例.
- 使用实现 Horizontal ListView 的 third-party 库的解决方案:听起来不错,但不是官方小部件让我想知道这是否是正确的方法。
- 使用 third-party 库的解决方案,该库实现了带有 cover flow effect 的非常好的画廊:与第二个解决方案相同的问题。
你看,主要问题是我已经开发了几个应用程序而不需要使用任何 third-party 库,除非真的有必要,否则我不想使用一个。
出于这个原因,我想问问你们,如果你们知道任何 solution/approach 结合:
- 本地组件。
- 易于使用。
- 回收。
编辑:
根据@Ewoks 和@CommonsWare 的建议,我尝试了 RecyclerView,结果证明它正是我需要的,而且没有我想象的那么复杂。
这是我使用的 links,以防有人发现它们有用:
- http://www.grokkingandroid.com/first-glance-androids-recyclerview/(一些理论)
- http://www.101apps.co.za/index.php/articles/android-recyclerview-and-picasso-tutorial.html(基本上是我在项目中使用的例子)
我对第二个示例进行了一些更改 link 我设法获得了我需要的两个画廊,其中第二个画廊列出了第一个画廊中所选类别中的所有菜肴。
结果如下:
正如我所说,得到那个结果并不难,我只需要在 LinearLayoutManager
[=31= 的构造函数中指定一个 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
,在其中我使用 [= 检查 mSelectedView
是否不为空(之前选择了一个项目) 111=] getSelectedView()
,在这种情况下,我将背景颜色改回透明。
不管mSelectedView
的值是多少,我把当前视图的背景色改为青色:
v.setBackgroundColor(Color.CYAN);
最后用当前选择的项目更新 mSelectedView
:
mParent.setSelectedView(v);
这可行,但结果很糟糕,因为它改变了整个视图的背景,而我认为只有图像应该以某种方式突出显示。
你知道我怎样才能更好地改变图片的风格吗?也许有一个开箱即用的解决方案来突出显示我不知道的所选项目。
非常感谢。
RecyclerView
with his build-in LayoutManagers of which I would recommend you GridLayout
which suits gallery purpose the best. In case you do not like that you can always implement your own LayoutManager by extending RecyclerView.LayoutManager
我希望这对一些初步指南有所帮助...;)
p.s。我当然不会推荐 CoverFlow,因为所有其他提到的 类 都提供了更丰富的 API。此外,它的实现缺乏很多性能问题。
我需要在我的应用程序中实现某种水平 ListView,以便在用户从第一个 ListView(类别)中选择一个项目后,第二个 ListView 显示与该所选项目相关的所有项目(类别中的产品) ).
我打算使用 Gallery
小部件,但由于它已被弃用,我试图找到一个好的替代品,但没有成功。
这是我发现的:
- 使用 ViewPager 的解决方案(参见 CommonsWare 的回答):有点复杂,没有关于如何处理简单
click
事件的示例. - 使用实现 Horizontal ListView 的 third-party 库的解决方案:听起来不错,但不是官方小部件让我想知道这是否是正确的方法。
- 使用 third-party 库的解决方案,该库实现了带有 cover flow effect 的非常好的画廊:与第二个解决方案相同的问题。
你看,主要问题是我已经开发了几个应用程序而不需要使用任何 third-party 库,除非真的有必要,否则我不想使用一个。
出于这个原因,我想问问你们,如果你们知道任何 solution/approach 结合:
- 本地组件。
- 易于使用。
- 回收。
编辑:
根据@Ewoks 和@CommonsWare 的建议,我尝试了 RecyclerView,结果证明它正是我需要的,而且没有我想象的那么复杂。
这是我使用的 links,以防有人发现它们有用:
- http://www.grokkingandroid.com/first-glance-androids-recyclerview/(一些理论)
- http://www.101apps.co.za/index.php/articles/android-recyclerview-and-picasso-tutorial.html(基本上是我在项目中使用的例子)
我对第二个示例进行了一些更改 link 我设法获得了我需要的两个画廊,其中第二个画廊列出了第一个画廊中所选类别中的所有菜肴。
结果如下:
正如我所说,得到那个结果并不难,我只需要在 LinearLayoutManager
[=31= 的构造函数中指定一个 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
,在其中我使用 [= 检查 mSelectedView
是否不为空(之前选择了一个项目) 111=] getSelectedView()
,在这种情况下,我将背景颜色改回透明。
不管mSelectedView
的值是多少,我把当前视图的背景色改为青色:
v.setBackgroundColor(Color.CYAN);
最后用当前选择的项目更新 mSelectedView
:
mParent.setSelectedView(v);
这可行,但结果很糟糕,因为它改变了整个视图的背景,而我认为只有图像应该以某种方式突出显示。
你知道我怎样才能更好地改变图片的风格吗?也许有一个开箱即用的解决方案来突出显示我不知道的所选项目。
非常感谢。
RecyclerView
with his build-in LayoutManagers of which I would recommend you GridLayout
which suits gallery purpose the best. In case you do not like that you can always implement your own LayoutManager by extending RecyclerView.LayoutManager
我希望这对一些初步指南有所帮助...;)
p.s。我当然不会推荐 CoverFlow,因为所有其他提到的 类 都提供了更丰富的 API。此外,它的实现缺乏很多性能问题。