我怎样才能使机器人水平的ListView?能使、机器人、水平、ListView

2023-09-11 12:51:25 作者:夏夜

可能重复:   在Android的水平的ListView?

就像Android的很多东西,你就不会认为这将是这样一个困难的问题,但哦~~,天哪,你是错的。而且,像在Android的很多事情,该API甚至没有提供一个合理的可扩展的起点。如果我要推出自己的ListView,当所有我想要的是拿东西,并把它在其一侧,我会被定罪。 \咆哮

好了,现在我做发烟,让我们来谈谈这个问题本身。我需要的是基本的东西完全一样的图库,但没有中央锁功能。我并不真的需要的ListView 的listSelector,但它是一个不错的到了。大多数情况下,我可以做我想做的与的LinearLayout 滚动型,但我需要孩子的观点来自一个 ListAdapter ,我真的想有一个观点回收。我的真正的不想写任何布局code。

我偷看到源$ C ​​$下其中的一些类...

画廊:的它看起来像我可以用库,如果我重写大部分的onXyz的方法,复制所有的源$ C ​​$ C,但与调用避免scrollIntoSlots()。但我敢肯定,如果我这样做,我会碰到一些成员字段是不可访问或其他不可预见的后果。

AbsSpinner:的因为 mRecycler 字段是包私人我怀疑我将能够扩展这个类

AbsListView:的它看起来像这个类只是针对垂直滚动,所以没有帮助有

适配器视图:的我从来没有直接扩展这个类。如果你告诉我,这是容易做到的,而且很容易推出自己的 RECYCLEBIN ,我会非常怀疑,但我给它一个镜头。

我想我可能复制的两个的 AbsSpinner 图库来得到什么,我希望......希望那些类不使用一些包私有变量,我无法访问。难道你们都认为这是一个好的做法呢?有没有人有任何教程或第三方解决方案,可以让我在正确的方向?

更新: 我到目前为止发现的唯一的解决办法就是做这一切我自己。既然问这个问题,我已经覆盖适配器视图并从头开始实施自己的Horizo​​ntalListView。真正覆盖画廊的中心锁功能的唯一方法是重写私人 scrollIntoSlots 的方法,我相信将需要生成一个子类,在运行时。如果你够大胆够做到这一点,可以说是最好的解决办法,但我不希望靠无证方法可能会改变。

Swathi EP以下建议我给了图库 OnTouchListener 并覆盖滚动功能。如果你不关心其在列表中一扔支持,或者如果它是没关系的意见捕捉到中心一扔动画结束,那么这个的将的为您的工作!但是,最终它仍然证明不可能消除中央锁功能不去除一扔支持。我问你,什么样的名单不扔?

所以,唉,这并没有为我工作。 :-(但是,如果你有兴趣在这种方法中,阅读...

我也不得不做出一些补充Swathi的code得到我想要的东西。在 GestureListener.onTouch ,除了委托给手势检测,我也只好返回true ACTION_UP ACTION_CANCEL 事件。成功地禁用中心锁功能,但它也急张禁用。我能够通过让自己的GestureListener委托给画廊的 onFling 方法重新启用猛冲。如果你想尝试一下,进入你的ApiDemos样品code,并与下面的code替换Gallery1.java类:

 进口com.example.android.apis.R;

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

公共类Gallery1延伸活动{

    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.gallery_1);

        //参考图库视图
        最后图库G =(图库论坛)findViewById(R.id.gallery);

        //适配器设置为我们的自定义适配器(如下图)
        g.setAdapter(新ImageAdapter(本));

        //设置一个项目点击监听器,只是举杯点击位置
        g.setOnItemClickListener(新OnItemClickListener(){
            公共无效onItemClick(适配器视图父,视图V,INT位置,长的id){
                Toast.makeText(Gallery1.this,+位置,Toast.LENGTH_SHORT).show();
            }
        });

        //手势检测
        最后GestureDetector gestureDetector =新GestureDetector(新MyGestureDetector(G));
        OnTouchListener gestureListener =新OnTouchListener(){
            @覆盖
            公共布尔onTouch(视图V,MotionEvent事件){
                布尔retVal的= gestureDetector.onTouchEvent(事件);
                INT行动= event.getAction();
                如果(行动== MotionEvent.ACTION_UP ||行动== MotionEvent.ACTION_CANCEL){
                    retVal的=真实;
                    onUp();
                }
                返回retVal的;
            }

            公共无效onUp(){
                //这里我只是照搬画廊的onUp()方法。
                的for(int i = g.getChildCount() -  1; I> = 0;我 - ){
                    g.getChildAt(我).SET pressed(假);
                }
                g.set pressed(假);
            }
        };
        g.setOnTouchListener(gestureListener);

        //我们也希望显示在画廊长pressed项目上下文菜单
        registerForContextMenu(G);
    }

    @覆盖
    公共无效onCreateContextMenu(文本菜单菜单,视图V,ContextMenuInfo menuInfo){
        menu.add(R.string.gallery_2_text);
    }

    @覆盖
    公共布尔onContextItemSelected(菜单项项){
        AdapterContextMenuInfo信息=(AdapterContextMenuInfo)item.getMenuInfo();
        Toast.makeText(这一点,龙preSS:+ info.position,Toast.LENGTH_SHORT).show();
        返回true;
    }

    公共类ImageAdapter扩展了BaseAdapter {
        INT mGalleryItemBackground;

        公共ImageAdapter(上下文C){
            mContext = C;
            //见RES /价值/ attrs.xml为的<申报,设置样式>定义
            // Gallery1。
            TypedArray A = obtainStyledAttributes(R.styleable.Gallery1);
            mGalleryItemBackground = a.getResourceId(
                    R.styleable.Gallery1_android_galleryItemBackground,0);
            a.recycle();
        }

        公众诠释getCount将(){
            返回mImageIds.length;
        }

        公共对象的getItem(INT位置){
            返回的位置;
        }

        众长getItemId(INT位置){
            返回的位置;
        }

        公共查看getView(INT位置,查看convertView,ViewGroup中父){
            ImageView的我=新ImageView的(mContext);

            i.setImageResource(mImageIds [位置]);
            i.setScaleType(ImageView.ScaleType.FIT_XY);
            i.setLayoutParams(新Gallery.LayoutParams(136,88));

            // pferred的$ P $图库项目背景
            i.setBackgroundResource(mGalleryItemBackground);

            返回我;
        }

        私人语境mContext;

        私人整数[] 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
        };
    }

    公共类MyGestureDetector扩展SimpleOnGestureListener {

        私人画廊的画廊;

        公共MyGestureDetector(图库图库){
            this.gallery =画廊;
        }

        @覆盖
        公共布尔onFling(MotionEvent E1,E2 MotionEvent,浮velocityX,
                浮动velocityY){
            返回gallery.onFling(E1,E2,velocityX,velocityY);
        }
    }

}
 

解决方案

看完这帖子以后,我已经实现了自己的水平列表视图。你可以找到它: http://www.dev-smart.com/?p=34 让我知道这是否可以帮助...

Possible Duplicate: Horizontal ListView in Android?

零费用入学,高质量就业 教育 就业 精准扶贫班招生啦

Like many things in Android, you wouldn't think this would be such a hard problem but ohhh, by golly, would you be wrong. And, like many things in Android, the API doesn't even provide a reasonably extensible starting point. I'll be damned if I'm going to roll my own ListView, when all I want is to take the thing and turn it on its side. \rant

Okay, now that I'm done fuming, let's talk about the problem itself. What I need is basically something exactly like the Gallery, but without the center-locking feature. I don't really need ListView's listSelector but it's a nice-to-have. Mostly, I could do what I want with a LinearLayout inside a ScrollView, but I need the child views to come from a ListAdapter and I would really like to have a view recycler. And I really don't want to write any layout code.

I peeked into the source code for some of these classes...

Gallery: It looks like I could use the Gallery if I override most of the 'onXyz' methods, copy all their source code, but refrain from calling scrollIntoSlots(). But I'm sure that if I do that I'll run into some member field that's inaccessible or some other unforeseen consequence.

AbsSpinner: Since the mRecycler field is package-private I doubt I'll be able to extend this class.

AbsListView: It looks like this class is only meant for vertical scrolling, so no help there.

AdapterView: I've never had to extend this class directly. If you tell me it's easy to do, and that it's easy to roll my own RecycleBin, I'll be very skeptical but I'll give it a shot.

I suppose I could possibly copy both AbsSpinner and Gallery to get what I want... hopefully those classes aren't using some package-private variable I can't access. Do y'all think that's a good practice? Does anyone have any tutorials or third-party solutions that might put me in the right direction?

Update: The only solution I've found so far is to do it all myself. Since asking this question, I have overridden AdapterView and implemented my own "HorizontalListView" from scratch. The only way to truly override the Gallery's center-locking feature is to override the private scrollIntoSlots method, which I believe would require generating a subclass at runtime. If you're bold enough to do that, it's arguably the best solution, but I don't want to rely on undocumented methods that could change.

Swathi EP below suggested that I give the Gallery an OnTouchListener and override the scroll functionality. If you don't care about having fling support in your list, or if it's okay for the views to snap to the center at the end of the fling animation, then this will work for you! However, in the end it still proves impossible to remove the center-locking feature without removing fling support. And I ask you, what kind of list doesn't fling?

So, alas, this did not work for me. :-( But if you're interested in this approach, read on...

I also had to make some additions to Swathi's code to get what I wanted. In GestureListener.onTouch, in addition to delegating to the gesture detector, I also had to return true for ACTION_UP and ACTION_CANCEL events. That successfully disabled the center-locking feature, but it also disabled flinging. I was able to re-enable fling by having my own GestureListener delegate to the Gallery's onFling method. If you want to try it out, go into your ApiDemos sample code and replace the Gallery1.java class with the following code:

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);
        }
    }

}

解决方案

After reading this post, I have implemented my own Horizontal listview. You can find it: http://www.dev-smart.com/?p=34 Let me know if this helps...