【问题标题】:Android StackView type of Layout with Horizontal SwipeAndroid StackView 类型的横向滑动布局
【发布时间】:2014-05-22 03:44:06
【问题描述】:

我正在构建一个需要“卡片组”UI 小部件的 Android 应用。

这是对可以执行以下操作的活动/布局示例的请求:

1) 垂直滑动支持:

列出一副可以垂直滚动/滑动的卡片。 StackView 会这样做,但我愿意接受任何运行良好的解决方案(例如,一些 CardUI 项目)

2) 水平滑动支持:

对于任何卡片,都有 2 个字典定义:

  • 如果我们向左滑动 - 那么我们可以看到定义 A。
  • 如果我们向右滑动,我们会看到定义 B
  • 水平滑动更新不会更新整个屏幕布局,只会更新被刷过的卡片。所以如果我向右滑动 Card2 看到 A2,我仍然有 Card1 在 A2 后面

例子:

[A1][Card1][B1]
[A2][Card2][B2]
[A3][Card3][B3]

我确实看到了这个相关的post here,那里的答案提供了一些提示和参考信息。但不幸的是,我仍在努力解决。

【问题讨论】:

    标签: android android-layout android-listview


    【解决方案1】:

    您有两种可能的方法:采用一些开源项目并根据您的需要对其进行调整,或者,将您的卡片刷卡构建为详细教程中的图像滑块。

    对于第一个选项,请查看 Github,在那里您会发现几个小项目,这些项目通常在垂直或水平滚动时使用 features 做卡片组。我想您可能会发现以下项目很有趣:

    • CardDeck:Deck of Cards for Android

    • DeckPicker:一个完整的 android anki droid 项目,在浏览器屏幕中具有卡片预览的一些附加功能。在预览屏幕卡将显示为card browser 窗口上的审阅模式。

    最后,如果您所做的额外更改看起来不错,则值得向原始项目提交补丁。

    对于第二种选择,对于您希望从头开始实施它的情况,然后采取简单的步骤,将您的项目扩展为更具体/更复杂的细节,根据您的意愿对其进行自定义。全屏图像滑块将适合该法案,它将包含视图页面的活动:

    activity_fullscreen_view.xml
    <?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.support.v4.view.ViewPager
            android:id="@+id/pager"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />
    
    </LinearLayout>
    

    还有一个带有全屏查看器的Java class

    public class FullScreenImageAdapter extends PagerAdapter {
    
        private Activity _activity;
        private ArrayList<String> _imagePaths;
        private LayoutInflater inflater;
    
        // constructor
        public FullScreenImageAdapter(Activity activity,
                ArrayList<String> imagePaths) {
            this._activity = activity;
            this._imagePaths = imagePaths;
        }
    
        @Override
        public int getCount() {
            return this._imagePaths.size();
        }
    
        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == ((RelativeLayout) object);
        }
    
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            ImageView imgDisplay;
            Button btnClose;
    
            inflater = (LayoutInflater) _activity
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View viewLayout = inflater.inflate(R.layout.layout_fullscreen_image, container,
                    false);
    
            imgDisplay = (ImageView) viewLayout.findViewById(R.id.imgDisplay);
            btnClose = (Button) viewLayout.findViewById(R.id.btnClose);
    
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inPreferredConfig = Bitmap.Config.ARGB_8888;
            Bitmap bitmap = BitmapFactory.decodeFile(_imagePaths.get(position), options);
            imgDisplay.setImageBitmap(bitmap);
    
            // close button click event
            btnClose.setOnClickListener(new View.OnClickListener() {           
                @Override
                public void onClick(View v) {
                    _activity.finish();
                }
            });
    
            ((ViewPager) container).addView(viewLayout);
    
            return viewLayout;
        }
    
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            ((ViewPager) container).removeView((RelativeLayout) object);
    
        }
    }
    

    然后你实现图片滑动horizontally,如:

    要添加垂直运动,只需添加额外的垂直布局:

    main.xml
    
    <?xml version="1.0" encoding="utf-8"?>
    
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    
        android:layout_width="fill_parent"
    
        android:layout_height="fill_parent"
    
        android:orientation="vertical" >
    
        <TextView
    
            android:layout_width="fill_parent"
    
            android:layout_height="wrap_content"
    
            android:text="Swipe Demo"
    
            android:gravity="center"
    
            android:layout_margin="10dip" />
    
            <LinearLayout
    
                android:layout_width="fill_parent"
    
                android:layout_height="fill_parent"
    
                android:orientation="vertical"
    
                android:gravity="center">
    
                     <ImageView
    
                         android:layout_width="wrap_content"
    
                         android:layout_height="wrap_content"
    
                         android:layout_gravity="center"
    
                         android:gravity="center"
    
                         android:layout_margin="10dip"
    
                         android:id="@+id/image_place_holder"/>
    
               </LinearLayout>
    
    </LinearLayout>
    

    这将允许您滑动东西vertically

    归根结底,您想要的是一个网格,例如垂直和水平滚动在一起。为此,您必须将垂直和水平滑动组合成table layout

    <?xml version="1.0" encoding="utf-8"?>
    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
                      android:layout_width="fill_parent"
                      android:layout_height="wrap_content">
    
        <HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
                      android:layout_width="wrap_content"
                      android:layout_height="fill_parent">
    
             <TableLayout
                      android:id="@+id/amortization"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content">
    
                  <TableRow
                      android:background="#ffff00">
                      <TextView
                           android:text="@string/amortization_1"
                           android:padding="3dip"/>
                      <TextView
                           android:text="@string/amortization_2"
                           android:padding="3dip"/>
                      <TextView
                           android:text="@string/amortization_3"
                           android:padding="3dip"/>
                      <TextView
                           android:text="@string/amortization_4"
                           android:padding="3dip"/>
                      <TextView
                           android:text="@string/amortization_5"
                           android:padding="3dip"/>
                      <TextView
                           android:text="@string/amortization_6"
                           android:padding="3dip"/>
                      <TextView
                           android:text="@string/amortization_7"
                           android:padding="3dip"/> 
                  </TableRow>
             </TableLayout>
        </HorizontalScrollView>
    </ScrollView>
    

    采取这些步骤并结合起来,可以达到你想要的效果。

    【讨论】:

    • 嗨,Avanz,感谢您的帖子和屏幕截图 - 它们对您有帮助。您为水平滑动显示的内容显示了全屏更改。我正在尝试实现前景中的视图可以水平滑动,并且它后面的视图保持原位。
    • 啊.. 我现在在您的注释中看到,我应该继续从您列出的起始代码进行迭代,并尝试结合不同的方法来满足手头的要求。感谢您分享我可以继续使用上述方法的一些不同方式的代码和想法。
    • 我在尝试使用您的建议来使用这个项目 github.com/cthibault/CardDeck,但我不知道如何运行代码以便我可以看到 Card & Deck UI 元素。我只看到 Hello World 屏幕和一个不工作的选项菜单。我确实将该根文件夹下的两个项目都导入了 ADT,并尝试同时运行这两个项目。测试项目似乎只是单元测试,没有任何 UI 可供查看。我猜您在运行 CardDeck 主项目时一定能够在您的环境中看到一些东西?
    • 你试过 DeckPicker 了吗?它甚至附带详细说明 - 如何编译:code.google.com/p/ankidroid/wiki/Contribution#Source_code
    【解决方案2】:

    试试这个示例代码-

    public class Main extends Activity {
    
        int position=0;
        LinearLayout full;
        Intent intent;
    
        public Integer[] images= {
                    R.drawable.image1, R.drawable.image2,
                    R.drawable.image3, R.drawable.image4,
                    R.drawable.image5, R.drawable.image6
        };
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);      
            full = (LinearLayout) findViewById(R.id.full);
            changeImage();
            ActivitySwipeDetector activitySwipeDetector = new ActivitySwipeDetector(this);
            full.setOnTouchListener(activitySwipeDetector);
        }
    
    
    
        private void changeImage(){
            full.setBackgroundResource(images[position]);
       }
    
        public class ActivitySwipeDetector implements View.OnTouchListener {
    
            static final String logTag = "ActivitySwipeDetector";
            static final int MIN_DISTANCE = 100;
            private float downX, upX;
            Activity activity;
    
            public ActivitySwipeDetector(Activity activity){
                this.activity = activity;
            }
    
            public void onRightToLeftSwipe(){
                Log.i(logTag, "RightToLeftSwipe!");
                if(position < images.length - 1){
                    position++;
                     changeImage();
                }
        }
    
            public void onLeftToRightSwipe(){
                Log.i(logTag, "LeftToRightSwipe!");
                if(position > 0){
                    position--;
                    changeImage();
               }
            }
    
            public boolean onTouch(View v, MotionEvent event) {
                switch(event.getAction()){
                    case MotionEvent.ACTION_DOWN: {
                        downX = event.getX();
                        return true;
                    }
                    case MotionEvent.ACTION_UP: {
                        upX = event.getX();
    
                        float deltaX = downX - upX;
    
                        // swipe horizontal?
                        if(Math.abs(deltaX) > MIN_DISTANCE){
                            // left or right
                            if(deltaX < 0) { this.onLeftToRightSwipe(); return true; }
                            if(deltaX > 0) { this.onRightToLeftSwipe(); return true; }
                        }
                        else {
                                Log.i(logTag, "Swipe was only " + Math.abs(deltaX) + " long, need at least " + MIN_DISTANCE);
                                return false; // We don't consume the event
                        }
    
    
                        return true;
                    }
                }
                return false;
            }
        }
    
        @Override
        protected void onPause() {
            super.onPause();
        }
    
        @Override 
        public void onResume()
        {
            super.onResume();
        }
    
        @Override
        protected void onStop() {
            super.onStop();
        }
    
        @Override 
        public void onBackPressed() {
            super.onBackPressed();
        }       
    }
    

    Xml-

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/full"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerInside"
        android:orientation="vertical" />
    

    【讨论】:

    • 我正在尝试此解决方案,但由于缺少声明,变量“mThumbId”出现错误;发生在这一行:if (position
    • @gnB 将 mThumbId 替换为图像。请参阅我编辑的帖子。
    • 嘿@gnB 你得到什么了吗我面临同样的问题
    • @Smith - 这最终比我当时准备的要复杂。我发现连接滑动监听器很棘手。我认为今天重新审视这一点会更直接 - 现在有更多知识渊博的 Android 人员在 SO 上,并且 API 已经向前移动。我建议使用您尝试过的代码开始新的帖子。正如您所看到的,它很快就会变得冗长 - 所以对于我的 0.02 美元,我会说代码应该精心设计,使其处于最低限度......人们更容易确定需要解决的地方。我很想看看它是怎么回事。最佳
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多