具有水平滑动的 Android StackView 布局类型

11

我正在开发一个Android应用程序,需要一个“Card Deck” UI小部件。

这是一个关于如何实现以下功能的活动/布局示例请求:

1) 竖向滑动支持:

列出一副可以垂直滚动/滑动的牌组。StackView 可以做到这一点,但我也可以接受任何其他行之有效的解决方案(例如,一些 CardUI 项目)

2) 横向滑动支持:

对于任何一张卡片,都有两个词典定义:

  • 如果我们向左滑动,则可以看到定义 A。
  • 如果我们向右滑动,则可以看到定义 B。
  • 横向滑动更新不会更新整个屏幕布局,只会更新被滑动的卡片。因此,如果我将 Card2 向右滑动以查看 A2,那么 A2 后面仍然会有 Card1。

示例:

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

我确实看到这篇相关的帖子,那里的答案提供了一些提示和参考信息...但不幸的是,我仍在努力弄清楚。

2个回答

8
你有两种可能的方法:采取某个开源项目并将其适应到您的需求中,或者通过详细的教程将您的刷卡器构建为图像滑块。
对于第一种选择,请在Github上查看,您会发现几个小型项目,这些项目通常使用垂直或水平滚动展示特性。我想您可能会对以下项目感兴趣:
  • CardDeck:Android上的纸牌堆

  • DeckPicker:一个完整的Android Anki Droid项目,具有一些额外功能,包括浏览器屏幕内的卡片预览。在预览屏幕上,卡片将显示为卡片浏览器窗口上的复习模式。

最后,如果您所做的附加更改看起来不错,可以值得向原始项目提交补丁。
对于第二种选择,如果您愿意从头开始实现它,那么请采取简单的步骤,根据您的意愿将项目逐渐发展成更具体/复杂的细节并进行自定义。一个全屏图像滑块会很合适,它将包括视图页面的活动:
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类

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

    }
}

然后您可以实现图片水平滑动 (如下): enter image description here 要添加垂直运动,只需包含附加的垂直布局即可。
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>

这将允许您垂直地滑动物品

enter image description here

在一天结束时,你希望拥有的是一个网格,例如垂直和水平滚动。为此,您必须将垂直和水平滑动结合到 表格布局中:

<?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,感谢您的帖子和屏幕截图 - 它们很有帮助。您所展示的水平滑动显示了全屏更改。我正在尝试实现在前景中可以水平滑动的视图,并且其后面的视图保持不变。 - Gene Bo
1
啊..我现在在你的笔记里看到了,我应该从你列出的起始代码开始迭代,并尝试结合不同的方法以适应手头的要求。感谢分享代码和一些不同的想法,我可以继续进行这个方法。 - Gene Bo
我尝试了您的建议,使用此项目https://github.com/cthibault/CardDeck,但我没有弄清楚如何运行代码,以便我可以看到Card&Deck UI元素。 我只看到Hello World屏幕和一个不起作用的选项菜单。 我确实将两个项目都导入ADT下的根文件夹,并尝试运行它们。 测试项目似乎只是单元测试,没有任何UI可供查看。 我猜当您运行主CardDeck项目时,您必须能够在您的环境中看到某些内容? - Gene Bo
你尝试过DeckPicker吗?它甚至附带了详细的说明 - 如何编译:http://code.google.com/p/ankidroid/wiki/Contribution#Source_code - Avanz
@gnB - 注意,http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work - Avanz

0

请尝试这个示例代码 -

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 < mThumbId.length - 1)。请问你能告诉我mThumbId应该如何设置吗?..我有点困惑,因为我认为mThumbId应该是一个int变量,用于引用已被触摸的ImageView引用。感谢您的帖子。 - Gene Bo
@gnB 将 mThumbId 替换为图像。请查看我编辑的帖子。 - Kanwaljit Singh
嘿 @gnB,你有解决这个问题的办法吗?我也遇到了同样的问题。 - user9550968
@Smith - 这个问题比当时我准备好的更加复杂。我发现连接滑动监听器很棘手。我认为今天重新审视这个问题会更加直接 - 现在SO上有更有知识的Android专家,而且API已经向前发展了。我建议您用您尝试过的代码开始一个新帖子。正如您所见,它可能很快变得冗长 - 所以根据我的经验,我认为应该将代码编写成最简单的形式...这样人们就可以更容易地确定需要解决的问题所在。我很想看看进展如何。最好的祝愿。 - Gene Bo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接