首页 > 其他分享 >让任意view具有滑动效果的SlideUp

让任意view具有滑动效果的SlideUp

时间:2023-05-01 16:10:17浏览次数:43  
标签:SlideUp void float private 滑动 View public view



让任意view具有滑动效果的SlideUp_xml



基本的类,只有一个:

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.animation.DecelerateInterpolator;

public class SlideUp implements View.OnTouchListener, ValueAnimator.AnimatorUpdateListener, Animator.AnimatorListener {
    private View view;
    private float touchableTop;
    private int autoSlideDuration = 300;
    private SlideListener slideListener;

    private ValueAnimator valueAnimator;
    private float slideAnimationTo;

    private float startPositionY;
    private float viewStartPositionY;
    private boolean canSlide = true;
    private float density;
    private float lowerPosition;
    private float viewHeight;

    private boolean hiddenInit;

    public SlideUp(final View view) {
        this.view = view;
        this.density = view.getResources().getDisplayMetrics().density;
        this.touchableTop = 300 * density;
        view.setOnTouchListener(this);
        view.setPivotY(0);
        createAnimation();
        view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                if (hiddenInit)
                {
                    viewHeight = view.getHeight();
                    hideImmediately();
                }
                view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }
        });
    }

    public boolean isVisible(){
        return view.getVisibility() == View.VISIBLE;
    }

    public void setSlideListener(SlideListener slideListener) {
        this.slideListener = slideListener;
    }

    public void setAutoSlideDuration(int autoSlideDuration) {
        this.autoSlideDuration = autoSlideDuration;
    }

    public float getAutoSlideDuration(){
        return this.autoSlideDuration;
    }

    public void setTouchableTop(float touchableTop) {
        this.touchableTop = touchableTop * density;
    }

    public float getTouchableTop() {
        return this.touchableTop/density;
    }

    public boolean isAnimationRunning(){
        return valueAnimator != null && valueAnimator.isRunning();
    }

    public void animateIn(){
        this.slideAnimationTo = 0;
        valueAnimator.setFloatValues(viewHeight, slideAnimationTo);
        valueAnimator.start();
    }

    public void animateOut(){
        this.slideAnimationTo = view.getHeight();
        valueAnimator.setFloatValues(view.getTranslationY(), slideAnimationTo);
        valueAnimator.start();
    }

    public void hideImmediately() {
        if (view.getHeight() > 0)
        {
            view.setTranslationY(viewHeight);
            view.setVisibility(View.GONE);
            notifyVisibilityChanged(View.GONE);
        }
        else {
            hiddenInit = true;
        }
    }

    private void createAnimation(){
        valueAnimator = ValueAnimator.ofFloat();
        valueAnimator.setDuration(autoSlideDuration);
        valueAnimator.setInterpolator(new DecelerateInterpolator());
        valueAnimator.addUpdateListener(this);
        valueAnimator.addListener(this);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        float touchedArea = event.getRawY() - view.getTop();
        if (isAnimationRunning())
        {
            return false;
        }
        switch (event.getActionMasked())
        {
            case MotionEvent.ACTION_DOWN:
                this.viewHeight = view.getHeight();
                startPositionY = event.getRawY();
                viewStartPositionY = view.getTranslationY();
                if (touchableTop < touchedArea)
                {
                    canSlide = false;
                }
                break;
            case MotionEvent.ACTION_MOVE:
                float difference = event.getRawY() - startPositionY;
                float moveTo = viewStartPositionY + difference;
                float percents = moveTo * 100 / view.getHeight();

                if (moveTo > 0 && canSlide){
                    notifyPercentChanged(percents);
                    view.setTranslationY(moveTo);
                }
                if (event.getRawY() > lowerPosition)
                {
                    lowerPosition = event.getRawY();
                }
                break;
            case MotionEvent.ACTION_UP:
                float slideAnimationFrom = view.getTranslationY();
                boolean mustSlideUp = lowerPosition > event.getRawY();
                boolean scrollableAreaConsumed = view.getTranslationY() > view.getHeight() / 5;

                if (scrollableAreaConsumed && !mustSlideUp)
                {
                    slideAnimationTo = view.getHeight();
                }
                else {
                    slideAnimationTo = 0;
                }
                valueAnimator.setFloatValues(slideAnimationFrom, slideAnimationTo);
                valueAnimator.start();
                canSlide = true;
                lowerPosition = 0;
                break;
        }
        return true;
    }

    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        float val = (float) animation.getAnimatedValue();
        view.setTranslationY(val);
        float percents = (view.getY() - view.getTop()) * 100 / viewHeight;
        notifyPercentChanged(percents);
    }

    private void notifyPercentChanged(float percent){
        if (slideListener != null)
        {
            slideListener.onSlide(percent);
        }
    }

    private void notifyVisibilityChanged(int visibility){
        if (slideListener != null)
        {
            slideListener.onVisibilityChanged(visibility);
        }
    }

    @Override
    public void onAnimationStart(Animator animator) {
        view.setVisibility(View.VISIBLE);
        notifyVisibilityChanged(View.VISIBLE);
    }

    @Override
    public void onAnimationEnd(Animator animator) {
        if (slideAnimationTo > 0)
        {
            view.setVisibility(View.GONE);
            notifyVisibilityChanged(View.GONE);
        }
    }

    @Override
    public void onAnimationCancel(Animator animator) {

    }

    @Override
    public void onAnimationRepeat(Animator animator) {

    }

    public interface SlideListener {
        void onSlide(float percent);
        void onVisibilityChanged(int visibility);
    }

}





基本用法:


创建一个任意类型的布局

<LinearLayout 

  android:id="@+id/slideView" 

  android:layout_width="match_parent" 

  android:layout_height="match_parent"/> 


获取这个view,SlideUp对象并传入view 

View slideView = findViewById(R.id.slideView); 

SlideUp slideUp = new SlideUp(slideView);



更复杂的例子:


import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;

import com.mancj.slideup.SlideUp;

public class SlideUpViewActivity extends AppCompatActivity {
    private SlideUp slideUp;
    private View dim;
    private View slideView;
    private FloatingActionButton fab;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_slide_up_view);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        slideView = findViewById(R.id.slideView);
        dim = findViewById(R.id.dim);
        fab = (FloatingActionButton) findViewById(R.id.fab);

        slideUp = new SlideUp(slideView);
        slideUp.hideImmediately();

        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                slideUp.animateIn();
                fab.hide();
            }
        });

        slideUp.setSlideListener(new SlideUp.SlideListener() {
            @Override
            public void onSlide(float percent) {
                dim.setAlpha(1 - (percent / 100));
            }

            @Override
            public void onVisibilityChanged(int visibility) {
                if (visibility == View.GONE)
                {
                    fab.show();
                }
            }
        });

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_slide_up_view, menu);
        return true;
    }
}




布局:


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:fitsSystemWindows="true"
    android:layout_height="match_parent"
    android:background="@color/colorPrimary">

    <FrameLayout
        android:alpha="0"
        android:id="@+id/dim"
        android:fitsSystemWindows="true"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/dimBg" />

    <android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.example.slideup.SlideUpViewActivity">

            <android.support.design.widget.AppBarLayout
                android:background="@android:color/transparent"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:elevation="0dp"
                app:elevation="0dp"
                android:theme="@style/AppTheme.AppBarOverlay">

                <android.support.v7.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    android:background="@android:color/transparent"
                    app:popupTheme="@style/AppTheme.PopupOverlay" />

            </android.support.design.widget.AppBarLayout>

            <include layout="@layout/content_slide_up_view" />

            <android.support.design.widget.FloatingActionButton
                android:id="@+id/fab"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom|end"
                android:layout_margin="@dimen/fab_margin"
                app:srcCompat="@drawable/ic_call_black_24dp"
                app:fabSize="normal" />

        </android.support.design.widget.CoordinatorLayout>
</RelativeLayout>


  • 让任意view具有滑动效果的SlideUp_android_02

  • 大小: 8 MB
  • main.zip (106.9 KB)
  • 下载次数: 0
  • 查看图片附件

标签:SlideUp,void,float,private,滑动,View,public,view
From: https://blog.51cto.com/u_5454003/6238915

相关文章

  • PhotoView点击放大图片效果
    使用的PhotoView是这个版本的,比较小巧,很好用,比github上另一个版本的瘦身很多:https://github.com/bm-x/PhotoView基本测试代码如下:importjava.util.ArrayList;importandroid.content.Context;importandroid.os.Bundle;importandroid.support.v7.w......
  • 使用ViewDragHelper实现的DragLayout开门效果
    先看一下图,有个直观的了解,向下拖动handle就“开门了”:此DragLayout继承自LinearLayout,这样使得布局变的简单。我把最顶部的View叫做HeadView,中间的叫“把手”HandleView,底部的叫ContentView,姑且这样叫着。只有把手可以拖动,下面的ContentView不可以!只要给Dr......
  • 迷你轻量级全方向完美滑动处理侧滑控件SlideLayout
    纯手工超级迷你轻量级全方向完美滑动处理侧滑控件(比官方supportv4包SlidingPaneLayout控件更加Q迷你,累计代码不足300行),支持上下左右有各种侧拉,可配置侧拉松手临界距离,支持单独使用、ListView、GridView、RecycleView、ScrollView、ViewPager等各种嵌套(作为item使用或......
  • 让ListView中有些长按时能弹出contextMenu,有些不能。
    android开发的时候,定义了一个listView,并为他设置了setOnCreateContextMenuListener的监听,但是这样做只能使这个listView中的所有项在长按的时候弹出contextMenu。我希望的是有些长按时能弹出contextMenu,有些不能。解决这个问题的办法是为这个listView设置s......
  • 设置ImageView的图片资源是直接来自SD卡
    在设置ImageView资源的时候,这时的图片是来自SD卡,查看API很容易就会看到view.setImageUri(Uriu)这个函数。所以一般会这样写:ImageViewview=(ImageView)findViewById(...);Filefile=newFile(path);Uriuri=Uri.from(file);view.setImageUr......
  • 在ScrollView添加一个ListView造成的滚动问题的简单解决办法
    已不推荐!推荐:http://gundumw100.iteye.com/blog/1732987正常来说,在ScrollView添加一个ListView后在真机上只会显示ListView的一行多一点,我也不理解为什么会这样,后来我把ListView的layout_height改成400dip,而不是用match_parent和wrap_content,我发现这样的话ListView就显示的多了很......
  • 关于如何获得ListView中选中项的值
    我已经获得了手机中保存的电话簿中联系人姓名和电话号码,并把它们显示在了一个ListView中,现在要实现的功能是当点击选中项时直接拨号,那么如何取得此时ListView中的号码?要显示联系人姓名和电话号码,那你现在肯定已经在listview的item里面放了两个控件吧,假如说......
  • TextView显示文字过长时添加阴影渐变消失效果
    TextView上显示的文字超过其最长限制的时候,要如何实现以下效果:values/styles.xml<stylename="AudioFileInfoOverlayText"><itemname="android:paddingLeft">4px</item><itemname="android:paddingBottom"......
  • 旋转ImageView和TextView的效果实现
    如图ImageView和TextView组成布局同时旋转。,求实现效果。经过几天研究终于实现如图效果。代码如下,给需要的人吧。还涉及到部分背景图的效果。publicclassIconViewGroupextendsViewGroup{TextViewmTextView;ImageViewmImageView;//显示对应的icon......
  • 圆角背景的ListView
    先定义一张圆角的图片shape_bg_listview.xml<?xmlversion="1.0"encoding="utf-8"?><shapexmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle"><gradient......