`

使用ViewDragHelper实现上拉效果

阅读更多
该例子位于https://github.com/umano/AndroidSlidingUpPanel

ViewDragHelper的用法:
http://flavienlaurent.com/blog/2013/08/28/each-navigation-drawer-hides-a-viewdraghelper/
Android ViewDragHelper完全解析 自定义ViewGroup神器
http://www.open-open.com/lib/view/open1437282182021.html

上拉前:


上拉中:



上拉后:



使用:
package com.sothree.slidinguppanel.demo;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.util.TypedValue;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;

import com.nineoldandroids.view.animation.AnimatorProxy;
import com.sothree.slidinguppanel.SlidingUpPanelLayout;
import com.sothree.slidinguppanel.SlidingUpPanelLayout.PanelSlideListener;

public class DemoActivity extends Activity {
    private static final String TAG = "DemoActivity";

    public static final String SAVED_STATE_ACTION_BAR_HIDDEN = "saved_state_action_bar_hidden";

    private SlidingUpPanelLayout mLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
        setContentView(R.layout.activity_demo);

        mLayout = (SlidingUpPanelLayout) findViewById(R.id.sliding_layout);
        mLayout.setPanelSlideListener(new PanelSlideListener() {
            @Override
            public void onPanelSlide(View panel, float slideOffset) {
                Log.i(TAG, "onPanelSlide, offset " + slideOffset);
                setActionBarTranslation(mLayout.getCurrentParalaxOffset());
            }

            @Override
            public void onPanelExpanded(View panel) {
                Log.i(TAG, "onPanelExpanded");

            }

            @Override
            public void onPanelCollapsed(View panel) {
                Log.i(TAG, "onPanelCollapsed");

            }

            @Override
            public void onPanelAnchored(View panel) {
                Log.i(TAG, "onPanelAnchored");
            }

            @Override
            public void onPanelHidden(View panel) {
                Log.i(TAG, "onPanelHidden");
            }
        });

        TextView t = (TextView) findViewById(R.id.main);
        t = (TextView) findViewById(R.id.name);
        t.setText(Html.fromHtml(getString(R.string.hello)));
        

        boolean actionBarHidden = savedInstanceState != null && savedInstanceState.getBoolean(SAVED_STATE_ACTION_BAR_HIDDEN, false);
        if (actionBarHidden) {
            int actionBarHeight = getActionBarHeight();
            setActionBarTranslation(-actionBarHeight);//will "hide" an ActionBar
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(SAVED_STATE_ACTION_BAR_HIDDEN, mLayout.isPanelExpanded());
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.demo, menu);
        MenuItem item = menu.findItem(R.id.action_toggle);
        if (mLayout != null) {
            if (mLayout.isPanelHidden()) {
                item.setTitle(R.string.action_show);
            } else {
                item.setTitle(R.string.action_hide);
            }
        }

        return true;
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        return super.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.action_toggle: {
                if (mLayout != null) {
                    if (!mLayout.isPanelHidden()) {
                        mLayout.hidePanel();
                        item.setTitle(R.string.action_show);
                    } else {
                        mLayout.showPanel();
                        item.setTitle(R.string.action_hide);
                    }
                }
                return true;
            }
            case R.id.action_anchor: {
                if (mLayout != null) {
                    if (mLayout.getAnchorPoint() == 1.0f) {
                        mLayout.setAnchorPoint(0.7f);
                        mLayout.expandPanel(0.7f);
                        item.setTitle(R.string.action_anchor_disable);
                    } else {
                        mLayout.setAnchorPoint(1.0f);
                        mLayout.collapsePanel();
                        item.setTitle(R.string.action_anchor_enable);
                    }
                }
                return true;
            }
        }
        return super.onOptionsItemSelected(item);
    }

    private int getActionBarHeight(){
        int actionBarHeight = 0;
        TypedValue tv = new TypedValue();
        if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
            actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
        }
        return actionBarHeight;
    }

    public void setActionBarTranslation(float y) {
        // Figure out the actionbar height
        int actionBarHeight = getActionBarHeight();
        // A hack to add the translation to the action bar
        ViewGroup content = ((ViewGroup) findViewById(android.R.id.content).getParent());
        int children = content.getChildCount();
        for (int i = 0; i < children; i++) {
            View child = content.getChildAt(i);
            if (child.getId() != android.R.id.content) {
                if (y <= -actionBarHeight) {
                    child.setVisibility(View.GONE);
                } else {
                    child.setVisibility(View.VISIBLE);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                        child.setTranslationY(y);
                    } else {
                        AnimatorProxy.wrap(child).setTranslationY(y);
                    }
                }
            }
        }
    }

    @Override
    public void onBackPressed() {
        if (mLayout != null && mLayout.isPanelExpanded() || mLayout.isPanelAnchored()) {
            mLayout.collapsePanel();
        } else {
            super.onBackPressed();
        }
    }
}



布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".DemoActivity" >

    <com.sothree.slidinguppanel.SlidingUpPanelLayout
        xmlns:sothree="http://schemas.android.com/apk/res-auto"
        android:id="@+id/sliding_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="bottom"
        sothree:panelHeight="68dp"
        sothree:shadowHeight="4dp"
        sothree:paralaxOffset="100dp"
        sothree:dragView="@+id/dragView">

        <!-- MAIN CONTENT -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:paddingTop="?android:attr/actionBarSize">
            <TextView
                android:id="@+id/main"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:text="Main Content"
                android:clickable="true"
                android:focusable="false"
                android:focusableInTouchMode="true"
                android:textSize="16sp" />
        </LinearLayout>

        <!-- SLIDING LAYOUT -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#eeeeee"
            android:orientation="vertical"
            android:clickable="true"
            android:focusable="false"
            android:id="@+id/dragView">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="68dp"
                android:orientation="horizontal">

                <TextView
                    android:id="@+id/name"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:textSize="14sp"
                    android:gravity="center_vertical"
                    android:paddingLeft="10dp"/>

            </LinearLayout>

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:scaleType="fitStart"
                android:src="@drawable/graphic" >
            </ImageView>
        </LinearLayout>
    </com.sothree.slidinguppanel.SlidingUpPanelLayout>

</RelativeLayout>



一个侧滑效果:
https://github.com/BlueMor/DragLayout
  • 大小: 125.1 KB
  • 大小: 421.5 KB
  • 大小: 871.3 KB
分享到:
评论
1 楼 greatjohn 2015-03-24  
很赞,楼主,现在这个开源的,升级过快。没有android stuido的开发者,示例工程都不能编译通过。正好楼主发布早起版本,可以使用。

相关推荐

    Android 抽屉式效果ViewDragHelper实现

    一个使用ViewDragHelper来实现的 安卓抽屉式滑动效果

    基于viewdraghelper实现的下拉刷新组件,集成了下拉刷新,底部加载更多,数据初始加载显示loading等功能。.zip

    本项目基于`ViewDragHelper`实现了一个这样的组件,它不仅提供了下拉刷新功能,还集成了底部加载更多以及数据初始加载时显示loading的效果。`ViewDragHelper`是Android SDK中的一个工具类,用于帮助开发者处理View的...

    VerticalDragLayout:布局可以使用ViewDragHelper绘制垂直

    VerticalDragLayout a layout can draw vertical use ViewDragHelper 使用ViewDragHelper实现拉伸的抽屉效果 Screenshots

    Android ViewDragHelper仿淘宝拖动加载效果

    于是就分析它的实现方式,感觉用ViewDragHelper可以很方便的实现这种效果。下面大致把我的思路分步骤写一下。先上图吧。 首先建工程什么的我就不多说了。咱从ViewDragHelper的实现开始说吧,ViewDragHelper一般用在...

    Android 仿 窗帘效果 和 登录界面拖动效果

    在Android中,我们可以使用ViewDragHelper和Scroller这两个关键组件来实现这一效果。ViewDragHelper可以帮助我们处理视图的拖动事件,而Scroller则用于平滑地滚动视图,提供类似物理的滚动体验。 1. **Scroller类**...

    android抽屉效果源码

    再次,为了实现拖动隐藏和显示的效果,源码可能使用了`ViewDragHelper`。这是一个Android提供的工具类,可以帮助开发者轻松地处理视图的拖放操作。`ViewDragHelper`能够处理边界限制、速度计算以及动画效果等细节,...

    安卓下拉上拉刷新相关-自定义下拉刷新下滑底部无限加载RecyclerView.zip

    这个压缩包“安卓下拉上拉刷新相关-自定义下拉刷新下滑底部无限加载RecyclerView.zip”显然是一个包含自定义实现下拉刷新和上拉加载组件的项目。下面我们将深入探讨这些关键知识点。 首先,下拉刷新(Pull-to-...

    android左滑插件

    开发者可以通过ViewDragHelper实现自定义的滑动效果,比如左侧滑动抽屉菜单。 4. **滑动事件处理**: 在Android中,滑动事件通常由MotionEvent类表示,通过onTouchEvent()方法处理。开发者需要监听ACTION_DOWN、...

    ListView上下拖拉

    2. **LoadMoreView**:对于上拉加载更多的功能,Android SDK并没有内置的组件,但可以通过自定义布局实现。在ListView的底部添加一个特殊的Footer View,当ListView滑动到底部时,显示加载提示并触发加载更多数据的...

    android实现自定义RelativeLayout可拖动、缩放、旋转TextView

    可以使用`ViewDragHelper`或`Scroller`来平滑处理拖动效果。 - 使用`onLayout()`方法合理安排子视图的位置,确保在缩放和旋转后依然正确显示。 5. **保存和恢复状态**: - 当Activity因配置改变而重建时,需要...

    仿QQ主界面

    在Android中,我们可以使用ViewDragHelper来处理拖拽事件,结合ObjectAnimator或ValueAnimator实现动画效果。在iOS中,类似的功能可以通过UIPanGestureRecognizer配合UIView的动画方法来完成。拖拽粘性控件的关键...

    安卓高级UI培训课程

    自绘控件、继承控件、组合控件、Scroller详解及源码...-流式布局、腾讯内部技术-QQ空间之打造个性化可拉伸头部控件、个性化滑动指示器、Material Design---RecyclerView实现时光轴效果、Android实现IOS Reveal特效)

    可从上往下拉的下拉抽屉式控件

    - 使用`ViewDragHelper`进行更精细的滑动控制,例如设置滑动速度、阻力等。 - 如果需要使用PopWindow,创建一个自定义的PopWindow实例,并在适当的时候显示。 5. **最佳实践**: - 抽屉宽度通常应设置为屏幕宽度...

    AndroidLowVersion_QQ_SlidingMenu

    3. **动画效果:**为了实现"往里伸缩"的效果,开发者通常会使用`ObjectAnimator`或`ValueAnimator`来控制菜单的滑动动画,同时结合`translationX`或`translationY`属性改变视图的位置,以实现平滑的过渡效果。...

    Android 新闻客户端

    3. **上拉刷新**:"新闻列表上拉刷新"是一个用户体验优化的特性,当用户滚动到列表底部时,可以自动加载更多内容。这需要集成像SwipeRefreshLayout这样的库,配合网络请求加载新数据。 4. **异步加载**:"异步加载...

    Android仿淘宝商品拖动查看详情及标题栏渐变功能

    在实际开发中,为了简化工作,可以使用诸如`SwipeRefreshLayout`和`NestedScrollView`等内置组件,它们提供了很多预设的交互效果,能快速实现下拉刷新和上拉加载。对于复杂的自定义滑动效果,可以使用`...

    安卓SlidingDrawer抽屉控件

    ViewDragHelper是Android提供的一个辅助类,用于处理视图之间的拖放操作,它能够轻松地实现平滑的滑动效果。 使用SlidingDrawer时,开发者需要在XML布局文件中定义控件,并设置handle和content的ID。例如: ```xml...

Global site tag (gtag.js) - Google Analytics