ListView 中的 Android Activity 转换

Posted

技术标签:

【中文标题】ListView 中的 Android Activity 转换【英文标题】:Android Activity Transition in a ListView 【发布时间】:2013-01-12 20:09:07 【问题描述】:

我正在尝试在 android 中完成以下 Activity 转换:

1中我们看到了一个普通的ListView。现在 (2),当我将手指放在 ListView 元素上并向左滑动手指时,所有其他 ListView 元素都会移开,但我的手指放在上面的元素除外。如果转换完成,“选定”的 ListView 元素会在屏幕上展开并显示一些内容。

问题:这种转换是否可以通过现有的 API 函数实现?

【问题讨论】:

Element里面有什么?展开高度是多少?你打算怎么把它倒回去? 我不知道这是否可能,也许你可以通过自定义这个库来实现这个github.com/bauerca/drag-sort-listview @Leonidos (3) 中的展开更像是动画。返回时(例如通过触摸后退箭头),您会看到 (1) 中的列表。在 (3) 中,我只需要一个动画,提示您选择的 ListView 元素的内容已显示。 我正在处理此问题,但没有时间继续:请查看github.com/sherifelkhatib/AnimationFactory 您是否尝试过使用以下组合:1)将视图复制到位图中(或制作它的辅助实例),2)在 listList 中的所有其他子项(或整个 listView原始设置为不可见)。 3) 完成后,将复制的视图添加到 listView 的父级列表中的全局位置。 4)从那里正常地为比例设置动画。 【参考方案1】:

如果你的目标是 JellyBean 或以上,你可以使用 ActivityOptions 类来自定义活动启动动画。

以下是实现此目的的伪代码:

Intent i = //the intent for the new activity
View v = //the selected list item
Bundle bundle = ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getWidth(), v.getHeight()).toBundle();
startActivity(i, bundle);

【讨论】:

【参考方案2】:

虽然@hasanghaforian 在技术上是正确的,但是继承 AdapterView 是非常困难的。我建议你采用这种方法。我已经包含了一个完整的工作示例。

    将您的 ListView 视图放在 relativeLayout 中 OnClick,为您的渲染器添加一个副本 查找渲染器相对于 ListView 父级的位置的全局坐标 将复制的渲染器添加到RelativeLayout(ListView的父级) 为 listView 制作动画 在该动画结束时,为您的新渲染器制作动画 利润!
public class MainActivity extends Activity 

    private RelativeLayout layout;
    private ListView listView;
    private MyRenderer selectedRenderer;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        layout = new RelativeLayout(this);
        setContentView(layout);
        listView = new ListView(this);
        RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
        layout.addView(listView, rlp);

        listView.setAdapter(new MyAdapter());
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() 
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) 

                // find out where the clicked view sits in relationship to the
                // parent container
                int t = view.getTop() + listView.getTop();
                int l = view.getLeft() + listView.getLeft();

                // create a copy of the listview and add it to the parent
                // container
                // at the same location it was in the listview
                selectedRenderer = new MyRenderer(view.getContext());
                RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(view.getWidth(), view
                        .getHeight());
                rlp.topMargin = t;
                rlp.leftMargin = l;
                selectedRenderer.textView.setText(((MyRenderer) view).textView.getText());
                layout.addView(selectedRenderer, rlp);
                view.setVisibility(View.INVISIBLE);

                // animate out the listView
                Animation outAni = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0f,
                        Animation.RELATIVE_TO_SELF, -1f, Animation.RELATIVE_TO_SELF, 0f,
                        Animation.RELATIVE_TO_SELF, 0f);
                outAni.setDuration(1000);
                outAni.setFillAfter(true);
                outAni.setAnimationListener(new Animation.AnimationListener() 
                    @Override
                    public void onAnimationStart(Animation animation) 
                    

                    @Override
                    public void onAnimationRepeat(Animation animation) 
                    

                    @Override
                    public void onAnimationEnd(Animation animation) 
                        ScaleAnimation scaleAni = new ScaleAnimation(1f, 
                                1f, 1f, 2f, 
                                Animation.RELATIVE_TO_SELF, 0.5f,
                                Animation.RELATIVE_TO_SELF, 0.5f);
                        scaleAni.setDuration(400);
                        scaleAni.setFillAfter(true);
                        selectedRenderer.startAnimation(scaleAni);
                    
                );

                listView.startAnimation(outAni);
            
        );
    

    public class MyAdapter extends BaseAdapter 
        @Override
        public int getCount() 
            return 10;
        

        @Override
        public String getItem(int position) 
            return "Hello World " + position;
        

        @Override
        public long getItemId(int position) 
            return position;
        

        @Override
        public View getView(int position, View convertView, ViewGroup parent) 
            MyRenderer renderer;
            if (convertView != null)
                renderer = (MyRenderer) convertView;
            else
                renderer = new MyRenderer(MainActivity.this);
            renderer.textView.setText(getItem(position));
            return renderer;
        
    

    public class MyRenderer extends RelativeLayout 

        public TextView textView;

        public MyRenderer(Context context) 
            super(context);
            setPadding(20, 20, 20, 20);
            setBackgroundColor(0xFFFF0000);

            RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(
                    RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
            rlp.addRule(CENTER_IN_PARENT);
            textView = new TextView(context);
            addView(textView, rlp);
        

    

【讨论】:

太棒了,比我预期的要少得多。在测试之后,我看到动画效果很好,但是在动画之后,如果我点击屏幕,列表就会显示出来,并且复制渲染不会从父布局中删除。我也想让它在不同的方向上工作(那真的很棒:D) 这是一个概念证明。根据您自己的需要实施它【参考方案3】:

标准ListView 的一个缺点是缺乏良好的物理特性(以及改变它的能力)。因此,如果你想改变它,你只需要实现你自己的视图。你必须扩展一个ViewGroup的子类,即AdapterView,这样AdapterView就会成为你的半List。

详情

    setAdapter(Adapter adapter) 方法中为您的 AdapterView 设置适配器。

    重写 onLayout 方法以将项目添加到您的 AdapterView。您必须测量项目并将其作为子视图添加到列表的正确位置(实际上是您的 AdapterView)。

    覆盖onTouchEvent(),这样你的列表就可以滚动了列表,当用户从屏幕上拿起他/她的手指时,您必须决定其他项目是否可见或必须扩展所选项目。

示例

Making your own 3D list(以及那篇文章的第 2 部分)很好地演示了我为您展示的内容。其目的是创建 3D 列表。您可以查看更多详细信息、sn-p 代码和完整代码。虽然您有将其更改为 onTouchEvent() 以达到您想要的效果。

注意您甚至可以在 API1 中执行此操作

希望对你有帮助!

【讨论】:

真的很有趣。我会看看这种方法。 很好的资源,但不要像“制作自己的 3d 列表”那样在 onTouch MotionEvent.ACTION_MOVE 的 AdapterView 中执行 requestLayout。这是非常低效的。【参考方案4】:

在您的 xml 文件中,在 ListView 下方,采用另一个线性布局/相对布局并根据您的需要进行设计,但要确保它的可见性必须消失。当您点击列表视图项时,用您的内容填充它并长按完成所有操作。对于动画,将其向左缩放。

【讨论】:

【参考方案5】:

当你按下该列表元素时,它应该调用动画,你必须通过动画。在那个动画中你应该设计它,如果你使用图像,在那些动画中意味着通过 9 个补丁图像

【讨论】:

以上是关于ListView 中的 Android Activity 转换的主要内容,如果未能解决你的问题,请参考以下文章

Android - ListView 中的延迟点击

ListView 中的 Android Activity 转换

android中的listview正常和悬停背景样式

更改 ListView 中的字体大小 - Android/Eclipse

Android中的倒置ListView?

Android:将数据库中的数据绑定到 ListView 中的 CheckBox?