Android中的水平ListView?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3240331/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:16:37  来源:igfitidea点击:

Horizontal ListView in Android?

androidlistviewgalleryhorizontal-scrolling

提问by Praveen

Is it possible to make the ListViewhorizontally? I have done this using a gallery view, but the selected item comes to the center of the screen automatically. I don't want the selected item at the same spot I clicked. How can I rectify this problem? My idea was to set the ListViewwith a horizontal scroll. Share your idea?

可以ListView横向制作吗?我使用图库视图完成了此操作,但所选项目会自动出现在屏幕中央。我不想在我点击的同一个地方选择项目。我该如何解决这个问题?我的想法是设置ListView水平滚动条。分享你的想法?

采纳答案by Devrath

As per Android Documentation RecyclerViewis the new way to organize the items in listview and to be displayed horizontally

根据 Android 文档RecyclerView是在列表视图中组织项目并水平显示的新方法

Advantages:

好处:

  1. Since by using Recyclerview Adapter, ViewHolder patternis automatically implemented
  2. Animation is easy to perform
  3. Many more features
  1. 由于使用 Recyclerview Adapter,自动实现了ViewHolder 模式
  2. 动画很容易执行
  3. 更多功能

More Information about RecyclerView:

更多信息RecyclerView

  1. grokkingandroid.com
  2. antonioleiva.com
  1. grokkingandroid.com
  2. 安东尼奥莱瓦网

Sample:

样本:

survivingwithandroid.com

Survivingwithandroid.com

Just add the below block to make the ListViewto horizontal from vertical

只需添加下面的块,使ListView从垂直到水平

Code-snippet

代码片段

LinearLayoutManager layoutManager= new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL, false);
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(layoutManager);

回答by Malachiasz

Paul doesn't bother to fix bugs of his library or accept users fixes. That's why I am suggesting another library which has similar functionality:

保罗不费心去修复他的库的错误或接受用户的修复。这就是为什么我建议另一个具有类似功能的库:

https://github.com/sephiroth74/HorizontalVariableListView

https://github.com/sephiroth74/Horizo​​ntalVariableListView

Update: on Jul 24, 2013 author (sephiroth74) released completely rewritten version based on code of android 4.2.2 ListView. I must say that it doesn't have all the errors which previous version had and works great!

更新:2013 年 7 月 24 日作者 (sephiroth74) 发布了基于 android 4.2.2 ListView 代码的完全重写版本。我必须说它没有以前版本有的所有错误并且效果很好!

回答by Xavi Gil

@Paul answer links to a great solution, but the code doesn't allow to use onClickListenerson items children (the callback functions are never called). I've been struggling for a while to find a solution and I've decided to post here what you need to modify in that code (in case somebody need it).

@Paul 回答链接到一个很好的解决方案,但代码不允许在项目子项上使用onClickListeners(回调函数永远不会被调用)。我一直在努力寻找解决方案,我决定在此处发布您需要在该代码中修改的内容(以防有人需要它)。

Instead of overriding dispatchTouchEventoverride onTouchEvent. Use the same code of dispatchTouchEventand delete the method (you can read the difference between the two here http://developer.android.com/guide/topics/ui/ui-events.html#EventHandlers)

而不是覆盖dispatchTouchEventoverride onTouchEvent。使用相同的代码dispatchTouchEvent和删除方法(你可以在这里阅读两者之间的区别http://developer.android.com/guide/topics/ui/ui-events.html#EventHandlers

@Override
public boolean onTouchEvent(MotionEvent event) {
    boolean handled = mGesture.onTouchEvent(event);
    return handled;
}

Then, add the following code which will decide to steal the event from the item children and give it to our onTouchEvent, or let it be handled by them.

然后,添加以下代码,该代码将决定从项目子项中窃取事件并将其提供给我们的onTouchEvent,或者由他们处理。

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    switch( ev.getActionMasked() ){
        case MotionEvent.ACTION_DOWN:
             mInitialX = ev.getX();
             mInitialY = ev.getY();             
             return false;
        case MotionEvent.ACTION_MOVE:
             float deltaX = Math.abs(ev.getX() - mInitialX);
             float deltaY = Math.abs(ev.getY() - mInitialY);
             return ( deltaX > 5 || deltaY > 5 );
        default:
             return super.onInterceptTouchEvent(ev);
    }
}

Finally, don't forget to declare the variables in your class:

最后,不要忘记在类中声明变量:

private float mInitialX;
private float mInitialY;

回答by klimat

Since Google introduced Android Support Library v7 21.0.0, you can use RecyclerView to scroll items horizontally. The RecyclerView widget is a more advanced and flexible version of ListView.

由于 Google 推出了 Android Support Library v7 21.0.0,您可以使用 RecyclerView 水平滚动项目。RecyclerView 小部件是 ListView 的更高级和更灵活的版本。

To use RecyclerView, just add dependency:

要使用 RecyclerView,只需添加依赖项:

com.android.support:recyclerview-v7:23.0.1

Here is a sample:

这是一个示例:

public class MyActivity extends Activity {

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

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

        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        recyclerView.setLayoutManager(layoutManager);

        MyAdapter adapter = new MyAdapter(myDataset);
        recyclerView.setAdapter(adapter);
    }
}

More info about RecyclerView:

有关 RecyclerView 的更多信息:

回答by Abhay Buch

This is a little (very) late, but I'm posting this in case someone comes by this later.

这有点(非常)晚了,但我会发布这个以防有人稍后来。

The Support Library as of the Android L preview has a RecyclerViewthat does exactly what you want.

Android L 预览版的支持库具有RecyclerView完全符合您要求的功能。

Right now, you can only get it through the L preview SDK and you need to set your minSdkto L. But you can copy all of the necessary files into your project and use them that way until L is officially out.

目前,您只能通过 L 预览版 SDK 获得它,并且您需要将您minSdkL. 但是您可以将所有必要的文件复制到您的项目中并以这种方式使用它们,直到 L 正式推出。

You can download the preview docs here.

您可以在此处下载预览文档。

Warning: The API for Recycler View may change and it may have bugs.

警告:Recycler View 的 API 可能会更改,并且可能存在错误。

Updated

更新

The source code for horizontal listview is:

水平列表视图的源代码是:

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

RecyclerView myList = findViewById(R.id.my_recycler_view);
myList.setLayoutManager(layoutManager);

回答by Siddhpura Amit

Download the jar file from here

这里下载 jar 文件

now put it into your libs folder, right click it and select 'Add as library'

现在将其放入您的 libs 文件夹中,右键单击它并选择“添加为库”

now in main.xml put this code

现在在 main.xml 中放置此代码

 <com.devsmart.android.ui.HorizontalListView
    android:id="@+id/hlistview"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    />

now in Activity class if you want Horizontal Listview with images then put this code

现在在 Activity 类中,如果您想要带有图像的 Horizo​​ntal Listview 然后放置此代码

  HorizontalListView hListView = (HorizontalListView) findViewById(R.id.hlistview);
    hListView.setAdapter(new HAdapter(this));


 private class HAdapter extends BaseAdapter {

    LayoutInflater inflater;

    public HAdapter(Context context) {
        inflater = LayoutInflater.from(context);

    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return Const.template.length;
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        HViewHolder holder;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.listinflate, null);
            holder = new HViewHolder();
            convertView.setTag(holder);

        } else {
            holder = (HViewHolder) convertView.getTag();
        }
        holder.img = (ImageView) convertView.findViewById(R.id.image);
        holder.img.setImageResource(Const.template[position]);
        return convertView;
    }

}

class HViewHolder {
    ImageView img;
}

回答by kc ochibili

Its actually very simple: simply Rotate the list view to lay on its side

它实际上非常简单:只需将列表视图旋转到其一侧即可

mlistView.setRotation(-90);

mlistView.setRotation(-90);

Then upon inflating the children, that should be inside the getView method. you rotate the children to stand up straight:

然后在给孩子充气时,应该在 getView 方法中。你旋转孩子们站直:

 mylistViewchild.setRotation(90);

Edit:if your ListView doesnt fit properly after rotation, place the ListView inside this RotateLayoutlike this:

编辑:如果旋转后您的 ListView 不适合,请将 ListView 放置在此RotateLayout 中,如下所示:

 <com.github.rongi.rotate_layout.layout.RotateLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:angle="90"> <!-- Specify rotate angle here -->

    <ListView
       android:layout_width="match_parent"
       android:layout_height="match_parent">
    </ListView>
</com.github.rongi.rotate_layout.layout.RotateLayout>

回答by fraggjkee

My solution is to simply use ViewPagerwidget. It isn't center-locked as Galleryand has a built-in features for recycling views (as ListView). You may see similar approach at Google Play app, whenever you deal with horizontally scrollable lists.

我的解决方案是简单地使用ViewPager小部件。它不是中心锁定的,Gallery并且具有用于回收视图的内置功能(如ListView)。每当您处理可水平滚动的列表时,您可能会在 Google Play 应用程序中看到类似的方法。

You just need to extend PagerAdapterand perform a couple of tweaks there:

您只需要在那里扩展PagerAdapter并执行一些调整:

public class MyPagerAdapter extends PagerAdapter {

    private Context mContext;

    public MyPagerAdapter(Context context) {
        this.mContext = context;
    }

    // As per docs, you may use views as key objects directly 
    // if they aren't too complex
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        View view = inflater.inflate(R.layout.item, null);
        container.addView(view);
        return view;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View) object);
    }

    @Override
    public int getCount() {
        return 10;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }

    // Important: page takes all available width by default,
    // so let's override this method to fit 5 pages within single screen
    @Override
    public float getPageWidth(int position) {
        return 0.2f;
    }
}

As result, you'll have horizontally scrollable widget with adapter, like this: enter image description here

结果,您将拥有带有适配器的水平可滚动小部件,如下所示: 在此处输入图片说明

回答by Abdul Aziz

Note: Android now supports horizontal list views using RecyclerView, so now this answer is deprecated, for information about RecyclerView : https://developer.android.com/reference/android/support/v7/widget/RecyclerView

注意:Android 现在支持使用 RecyclerView 的水平列表视图,所以现在这个答案已被弃用,有关 RecyclerView 的信息:https: //developer.android.com/reference/android/support/v7/widget/RecyclerView

I have developed a logic to do it without using any external horizontal scrollview library, here is the horizontal view that I achieved and I have posted my answer here:https://stackoverflow.com/a/33301582/5479863

我开发了一个逻辑来完成它而不使用任何外部水平滚动视图库,这是我实现的水平视图,我已经在这里发布了我的答案:https://stackoverflow.com/a/33301582/5479863

My json response is this:

我的 json 响应是这样的:

{"searchInfo":{"status":"1","message":"Success","clist":[{"id":"1de57434-795e-49ac-0ca3-5614dacecbd4","name":"Theater","image_url":"http://52.25.198.71/miisecretory/category_images/movie.png"},{"id":"62fe1c92-2192-2ebb-7e92-5614dacad69b","name":"CNG","image_url":"http://52.25.198.71/miisecretory/category_images/cng.png"},{"id":"8060094c-df4f-5290-7983-5614dad31677","name":"Wine-shop","image_url":"http://52.25.198.71/miisecretory/category_images/beer.png"},{"id":"888a90c4-a6b0-c2e2-6b3c-561788e973f6","name":"Chemist","image_url":"http://52.25.198.71/miisecretory/category_images/chemist.png"},{"id":"a39b4ec1-943f-b800-a671-561789a57871","name":"Food","image_url":"http://52.25.198.71/miisecretory/category_images/food.png"},{"id":"c644cc53-2fce-8cbe-0715-5614da9c765f","name":"College","image_url":"http://52.25.198.71/miisecretory/category_images/college.png"},{"id":"c71e8757-072b-1bf4-5b25-5614d980ef15","name":"Hospital","image_url":"http://52.25.198.71/miisecretory/category_images/hospital.png"},{"id":"db835491-d1d2-5467-a1a1-5614d9963c94","name":"Petrol-Pumps","image_url":"http://52.25.198.71/miisecretory/category_images/petrol.png"},{"id":"f13100ca-4052-c0f4-863a-5614d9631afb","name":"ATM","image_url":"http://52.25.198.71/miisecretory/category_images/atm.png"}]}}

Layout file :

布局文件:

    <?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:orientation="vertical"
    android:weightSum="5">    
    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="4" />
    <HorizontalScrollView
        android:id="@+id/horizontalScroll"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">

        <LinearLayout
            android:id="@+id/ll"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:orientation="horizontal">    
        </LinearLayout>
    </HorizontalScrollView>
</LinearLayout>

class file:

类文件:

LinearLayout linearLayout = (LinearLayout) findViewById(R.id.ll);
        for (int v = 0; v < collectionInfo.size(); v++) {
            /*---------------Creating frame layout----------------------*/

            FrameLayout frameLayout = new FrameLayout(ActivityMap.this);
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, getPixelsToDP(90));
            layoutParams.rightMargin = getPixelsToDP(10);
            frameLayout.setLayoutParams(layoutParams);

            /*--------------end of frame layout----------------------------*/

            /*---------------Creating image view----------------------*/
            final ImageView imgView = new ImageView(ActivityMap.this); //create imageview dynamically
            LinearLayout.LayoutParams lpImage = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
            imgView.setImageBitmap(collectionInfo.get(v).getCatImage());
            imgView.setLayoutParams(lpImage);
            // setting ID to retrieve at later time (same as its position)
            imgView.setId(v);
            imgView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    // getting id which is same as its position
                    Log.i(TAG, "Clicked on " + collectionInfo.get(v.getId()).getCatName());
                    // getting selected category's data list
                    new GetSelectedCategoryData().execute(collectionInfo.get(v.getId()).getCatID());
                }
            });
            /*--------------end of image view----------------------------*/

            /*---------------Creating Text view----------------------*/
            TextView textView = new TextView(ActivityMap.this);//create textview dynamically
            textView.setText(collectionInfo.get(v).getCatName());
            FrameLayout.LayoutParams lpText = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM | Gravity.CENTER);
            // Note: LinearLayout.LayoutParams 's gravity was not working so I putted Framelayout as 3 paramater is gravity itself
            textView.setTextColor(Color.parseColor("#43A047"));
            textView.setLayoutParams(lpText);
            /*--------------end of Text view----------------------------*/

            //Adding views at appropriate places
            frameLayout.addView(imgView);
            frameLayout.addView(textView);
            linearLayout.addView(frameLayout);

        }

 private int getPixelsToDP(int dp) {
        float scale = getResources().getDisplayMetrics().density;
        int pixels = (int) (dp * scale + 0.5f);
        return pixels;
    }

trick that is working here is the id that I have assigned to ImageView "imgView.setId(v)" and after that applying onClickListener to that I am again fetching the id of the view....I have also commented inside the code so that its easy to understand, I hope this may be very useful... Happy Coding... :)

在这里工作的技巧是我分配给 ImageView“imgView.setId(v)”的 id,然后将 onClickListener 应用到我再次获取视图的 id ......我也在代码中进行了评论它易于理解,我希望这可能非常有用......快乐编码...... :)

http://i.stack.imgur.com/lXrpG.png

http://i.stack.imgur.com/lXrpG.png

回答by mobileideafactory.com

You can use RecyclerView in the support library. RecyclerView is a generalized version of ListView that supports:

您可以在支持库中使用 RecyclerView。RecyclerView 是 ListView 的通用版本,支持:

  • A layout manager for positioning items
  • Default animations for common item operations
  • 用于定位项目的布局管理器
  • 常见项目操作的默认动画

Android Recycler View Docs

Android Recycler 查看文档