android - 如何设计可调整大小的 ViewPager 画廊?

标签 android android-layout android-viewpager android-image android-gallery

我已经尝试为此想出一个自定义解决方案,但我对 android UI 不太熟悉。

相关应用程序可在此处找到:https://play.google.com/store/apps/details?id=com.expedia.bookings&hl=en

基本上,当用户向下滚动时,图库的大小会不断减小(连同图像),如果用户向下滚动足够多,图库就会消失。当用户向上滚动顶部时,图库的大小不断增加。如果用户向上滚动足够多,图库就会占据整个屏幕。

研究告诉我,与 onScrollChanged 事件类似的东西可能有用?

更有经验的人可以对此有更多的说明吗?

最佳答案

您需要向寻呼机添加触摸监听器,然后区分水平移动和垂直移动。我猜这就是你要找的东西

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:gravity="bottom"
              android:orientation="vertical">


    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:background="#8888">

    </android.support.v4.view.ViewPager>
</LinearLayout>

一个简单的寻呼机适配器 PagerAdapter.java

package com.virtoos.tests;

public class PagerAdapter extends android.support.v4.view.PagerAdapter {
    private static final int[] WELCOME_IMAGES = new int[] {
            R.drawable.ic_launcher,
            R.drawable.ic_launcher,
            R.drawable.ic_launcher,
            R.drawable.ic_launcher,
            R.drawable.ic_launcher
    };

    Context mContext;
    LayoutInflater mLayoutInflater;

    public PagerAdapter(Context context){
        mContext = context;
        mLayoutInflater = LayoutInflater.from(context);
    }

    @Override
    public Object instantiateItem(ViewGroup parent, int position){
        ImageView imageView = new ImageView(mContext);
        imageView.setImageResource(WELCOME_IMAGES[position]);
        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
        imageView.setLayoutParams(lp);
        imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
        parent.addView(imageView);
        return imageView;
    }

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

    @Override
    public int getCount(){
        return WELCOME_IMAGES.length;
    }

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

}

最后一个带有触摸处理程序的 Activity 类

MainActivity.java

package com.virtoos.tests;

public class MainActivity extends FragmentActivity {
    private ViewPager pager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        pager = (ViewPager)findViewById(R.id.pager);
        pager.setAdapter(new PagerAdapter(this));


        pager.setOnTouchListener(dragTouchListener);
        ViewConfiguration vc = ViewConfiguration.get(this);
        slop = vc.getScaledTouchSlop();
    }

    private float downY;
    private int slop;
    private VelocityTracker velocityTracker;
    private boolean isVerticalScroll = false;
    private View.OnTouchListener dragTouchListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if(event.getAction()==MotionEvent.ACTION_DOWN){
                downY = event.getY();
                velocityTracker = VelocityTracker.obtain();
                velocityTracker.addMovement(event);
            } else if(event.getAction()==MotionEvent.ACTION_MOVE){
                float deltaY = event.getY() - downY;
                float deltaMode = Math.abs(deltaY);

                velocityTracker.addMovement(event);
                velocityTracker.computeCurrentVelocity(1000);

                float velocityX = Math.abs(velocityTracker.getXVelocity());
                float velocityY = Math.abs(velocityTracker.getYVelocity());
                if (isVerticalScroll || (deltaMode > slop && velocityY > velocityX)) {
                    //this.getParent().requestDisallowInterceptTouchEvent(true);
                    LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) pager.getLayoutParams();
                    lp.height = (int) (lp.height-deltaY);
                    pager.setLayoutParams(lp);
                    isVerticalScroll = true;
                }else {
                    isVerticalScroll = false;
                    return false;
                }

            } else if(event.getAction()==MotionEvent.ACTION_UP){
                if(!isVerticalScroll) return false;
                //float deltaY = event.getRawY() - downY;
                //float deltaMode = Math.abs(deltaY);
                downY = 0;
                isVerticalScroll = false;
                //float velocityY = Math.abs(velocityTracker.getYVelocity());
                velocityTracker.recycle();
                velocityTracker = null;
                /*if((velocityY>100 && deltaMode > slop) ) {
                    if(*//*pager above half of the screen*//*){
                        animateOpen();
                    }else {
                        animateClose();
                    }
                    mGestureDetector.onTouchEvent(event);
                    return true;
                }*/
            }
            //return mGestureDetector.onTouchEvent(event);
            return true;
        }
    };

}

您可以通过添加 GestureDetector 来增强此示例,以处理 onFling 手势,这将为您提供更身临其境的控制

关于android - 如何设计可调整大小的 ViewPager 画廊?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17196978/

相关文章:

java - 基于android设备的不同fragment布局

android - 如何取消处于运行状态的AsyncTask。

android - 从 getItemPosition 更新 ViewPager 中的 fragment

带有tabhost的android activitygroup,键盘不显示

文件类型的 Android Intent 失败

android - 如何禁用 onitem 单击 ListView 中的特定行

android - 如何在 Android 中自定义 Spinner

android - 用更短的拖动使 ViewPager 对齐

android - TabFragment 中的 ViewPager 未再次加载

android - 结合webview-android的搜索栏和地址栏