android - 如何在 Android 中制作水平 ListView?

标签 android listview gallery

这个问题在这里已经有了答案:




9年前关闭。




Possible Duplicate:
Horizontal ListView in Android?



就像 Android 中的许多事情一样,您不会认为这会是一个如此困难的问题,但是哦,天哪,您会错吗?而且,就像 Android 中的许多东西一样,API 甚至没有提供一个可合理扩展的起点。如果我要推出自己的 ListView,我会被诅咒的,而我想要的只是拿走东西并把它翻过来。\咆哮

好的,既然我已经完成了发烟,让我们谈谈问题本身。我需要的基本上与 Gallery 完全相同。 ,但没有中心锁定功能。我真的不需要ListView的 listSelector 但它是一个不错的选择。大多数情况下,我可以用 LinearLayout 做我想做的事。在 ScrollView 内,但我需要 subview 来自 ListAdapter我真的很想有一个 View 回收器。而且我真的不想写任何布局代码。

我查看了其中一些类的源代码......

画廊:如果我重写大多数“onXyz”方法,复制它们的所有源代码,但不要调用 scrollIntoSlots(),看起来我可以使用画廊。 .但我敢肯定,如果我这样做,我会遇到一些无法访问的成员字段或其他无法预料的后果。

AbsSpinner:自从 mRecycler字段是包私有(private)的我怀疑我是否能够扩展这个类。

AbsListView:看起来这个类只用于垂直滚动,所以没有帮助。

AdapterView:我从来不用直接扩展这个类。如果你告诉我这很容易做,而且很容易推出我自己的RecycleBin ,我会非常怀疑,但我会试一试。

我想我可以复制两个 AbsSpinnerGallery得到我想要的......希望这些类没有使用我无法访问的一些包私有(private)变量。大家觉得这是个好习惯吗?有没有人有任何教程或第三方解决方案可以让我朝着正确的方向前进?

更新:
到目前为止,我发现的唯一解决方案就是自己做。自从提出这个问题后,我已经覆盖了 AdapterView并从头开始实现我自己的“Horizo​​ntalListView”。真正覆盖 Gallery 的中心锁定功能的唯一方法是覆盖私有(private) scrollIntoSlots方法,我认为这需要在运行时生成一个子类。如果你有足够的胆量这样做,这可以说是最好的解决方案,但我不想依赖可能会改变的无证方法。

下面的 Swathi EP 建议我给 Gallery一个 OnTouchListener并覆盖滚动功能。如果您不关心列表中是否有 throw 支持,或者 View 可以在 throw 动画结束时捕捉到中心,那么这对您有用!然而,最终仍然证明在不移除弹射支撑的情况下移除中心锁定功能是不可能的。我问你,什么样的 list 不会扔?

所以,唉,这对我不起作用。 :-( 但是,如果您对这种方法感兴趣,请继续阅读...

我还必须对 Swathi 的代码进行一些补充才能得到我想要的。在 GestureListener.onTouch ,除了委派给手势检测器之外,我还必须为 ACTION_UP 返回 true和 ACTION_CANCEL事件。这成功地禁用了中心锁定功能,但它也禁用了 throw 。我可以通过让我自己的 GestureListener 代表到 Gallery 的 onFling 来重新启用 throw 。方法。如果您想尝试一下,请进入您的 ApiDemos 示例代码并将 Gallery1.java 类替换为以下代码:
import com.example.android.apis.R;

import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.GestureDetector;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.View.OnTouchListener;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;

public class Gallery1 extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.gallery_1);

        // Reference the Gallery view
        final Gallery g = (Gallery) findViewById(R.id.gallery);

        // Set the adapter to our custom adapter (below)
        g.setAdapter(new ImageAdapter(this));

        // Set a item click listener, and just Toast the clicked position
        g.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView parent, View v, int position, long id) {
                Toast.makeText(Gallery1.this, "" + position, Toast.LENGTH_SHORT).show();
            }
        });

        // Gesture detection
        final GestureDetector gestureDetector = new GestureDetector(new MyGestureDetector(g));
        OnTouchListener gestureListener = new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                boolean retVal = gestureDetector.onTouchEvent(event);
                int action = event.getAction();
                if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
                    retVal = true;
                    onUp();
                }
                return retVal;
            }

            public void onUp() {
                // Here I am merely copying the Gallery's onUp() method.
                for (int i = g.getChildCount() - 1; i >= 0; i--) {
                    g.getChildAt(i).setPressed(false);
                }
                g.setPressed(false);
            }
        };
        g.setOnTouchListener(gestureListener);

        // We also want to show context menu for longpressed items in the gallery
        registerForContextMenu(g);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        menu.add(R.string.gallery_2_text);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
        Toast.makeText(this, "Longpress: " + info.position, Toast.LENGTH_SHORT).show();
        return true;
    }

    public class ImageAdapter extends BaseAdapter {
        int mGalleryItemBackground;

        public ImageAdapter(Context c) {
            mContext = c;
            // See res/values/attrs.xml for the <declare-styleable> that defines
            // Gallery1.
            TypedArray a = obtainStyledAttributes(R.styleable.Gallery1);
            mGalleryItemBackground = a.getResourceId(
                    R.styleable.Gallery1_android_galleryItemBackground, 0);
            a.recycle();
        }

        public int getCount() {
            return mImageIds.length;
        }

        public Object getItem(int position) {
            return position;
        }

        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            ImageView i = new ImageView(mContext);

            i.setImageResource(mImageIds[position]);
            i.setScaleType(ImageView.ScaleType.FIT_XY);
            i.setLayoutParams(new Gallery.LayoutParams(136, 88));

            // The preferred Gallery item background
            i.setBackgroundResource(mGalleryItemBackground);

            return i;
        }

        private Context mContext;

        private Integer[] mImageIds = {
                R.drawable.gallery_photo_1,
                R.drawable.gallery_photo_2,
                R.drawable.gallery_photo_3,
                R.drawable.gallery_photo_4,
                R.drawable.gallery_photo_5,
                R.drawable.gallery_photo_6,
                R.drawable.gallery_photo_7,
                R.drawable.gallery_photo_8
        };
    }

    public class MyGestureDetector extends SimpleOnGestureListener {

        private Gallery gallery;

        public MyGestureDetector(Gallery gallery) {
            this.gallery = gallery;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 
                float velocityY) {
            return gallery.onFling(e1, e2, velocityX, velocityY);
        }
    }

}

最佳答案

看完这篇文章,我实现了自己的水平ListView .你可以在这里找到它:http://dev-smart.com/horizontal-listview/让我知道这是否有帮助。

关于android - 如何在 Android 中制作水平 ListView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3877040/

相关文章:

java - 旋转期间无法保存 fragment 状态

Android - 替换已弃用的通知类

c# - 从 FrameworkElementFactory 获取值

Android - 如何强制画廊重绘其 View ?

android - Flutter:升级Play商店的版本代码

android - 使用 GroundOverlays 时考虑地球的曲率

Android禁用 ListView 项目

java - 带有 onItemClick 位置的 ListView

Android:画廊 View 中的动画?

jquery - 左对齐画廊的最后一行