android 蒙版 上滑动画,Android 开发第三弹:自定义左右菜单(滑动动画+蒙版效果)...

下面的截图……哎,因为1080P在Windows 10上虽然适配了,但大部分软件并没有跟上,比如某个录制GIF的软件,所以这里有一定的偏移导致画面不完整,但效果大概就是这么一个效果了。

5c305ac45860a0f025eeedad9ef75158.gif

MainUI.java

首先需要这么一个类,在这里一些UI的滑动呀之类的都会定义。首先吧,定义好这些变量,当然了,实际开发过程中肯定需要哪一个就添加上哪一个的。

private Context context; // 上下文

private FrameLayout leftMenu; // 左边部分

private FrameLayout middleMenu; // 中间部分

private FrameLayout rightMenu; // 右边部分

private FrameLayout middleMask; // 蒙版效果

private Scroller mScroller; // 滑动动画

public static final int ID = 0; // ID

public static final int LEFT_ID = ID+0xaabbcc;

public static final int MIDDLE_ID = ID+0xaaccbb;

public static final int RIGHT_ID = ID+0xccbbaa;

构造函数也是不能少的。

public MainUI(Context context) {

super(context);

initView(context);

}

public MainUI(Context context, AttributeSet attrs) {

super(context, attrs);

initView(context);

}

initView就是用来初始化视图的,相应的功能我都写在注释上了,就不多废话了。

// 初始化视图

private void initView(Context context){

this.context=context;

mScroller = new Scroller(context,new DecelerateInterpolator());

leftMenu=new FrameLayout(context);

middleMenu = new FrameLayout(context);

rightMenu = new FrameLayout(context);

middleMask = new FrameLayout(context);

leftMenu.setBackgroundColor(Color.RED); // 设置背景颜色

middleMenu.setBackgroundColor(Color.GREEN);

rightMenu.setBackgroundColor(Color.RED);

middleMask.setBackgroundColor(0x88000000);

leftMenu.setId(LEFT_ID);

middleMenu.setId(MIDDLE_ID);

rightMenu.setId(RIGHT_ID);

addView(leftMenu); // 添加至View

addView(middleMenu);

addView(rightMenu);

addView(middleMask);

middleMask.setAlpha(0); // 设置middleMask的透明度

}

然后就是它们的一些布局呀,balabala……

@Override

protected void onMeasure(int widthMeasureSepc, int heightMeasureSpec){

super.onMeasure(widthMeasureSepc, heightMeasureSpec);

middleMenu.measure(widthMeasureSepc, heightMeasureSpec);

middleMask.measure(widthMeasureSepc,heightMeasureSpec);

int realWidth = MeasureSpec.getSize(widthMeasureSepc); // 获取实际(屏幕)宽度

int tempWidthMeasure = MeasureSpec.makeMeasureSpec(

(int)(realWidth*0.7f), MeasureSpec.EXACTLY); // 左右侧的宽度为中间宽度的0.7

leftMenu.measure(tempWidthMeasure, heightMeasureSpec); // 左右侧的高度和中间的一样

rightMenu.measure(tempWidthMeasure, heightMeasureSpec);

}

@Override

protected void onLayout(boolean changed, int l, int t, int r,int b){ // l,t,r,b分别为中间部分的左、上、右、下边界

super.onLayout(changed, l, t, r, b); // 设置布局

middleMenu.layout(l, t, r, b); // 中间部分的四个边界不变

middleMask.layout(l, t, r, b); // 蒙版的四个边界和中间部分一样

leftMenu.layout(l - leftMenu.getMeasuredWidth(), t, r, b); // 左侧部分的左边边界等于中间部分的左边边界减去左侧部分的宽度

rightMenu.layout(l + middleMenu.getMeasuredWidth(), t, // 右侧部分的左边边界则等于中间部分的左边边界加上中间部分的宽度

l + middleMenu.getMeasuredWidth() + // 右侧部分的右边边界等于中间部分的左边边界加上中间部分的宽度加上右侧部分的宽度

rightMenu.getMeasuredWidth(), b);

}

public float onMiddleMask(){

System.out.println("透明度"+middleMask.getAlpha());

return middleMask.getAlpha();

}

@Override

public void scrollTo(int x, int y){

super.scrollTo(x,y);

onMiddleMask(); // 输出透明度

int curX = Math.abs(getScrollX());

float scale = curX/(float)leftMenu.getMeasuredWidth(); // 设置透明度的渐变

middleMask.setAlpha(scale);

}

再用两个布尔值来确定是否在左右滑动等。

private boolean isTestComete; // 测试是否完成

private boolean isleftrightevent; // 判断是否是左右滑动

@Override

public boolean dispatchTouchEvent(MotionEvent ev){

if(!isTestComete){ // 没有完成滑动动作

getEventType(ev); // 继续调用事件进行判断

return true;

}

if(isleftrightevent){ // 左右滑动

switch (ev.getActionMasked()) {

case MotionEvent.ACTION_MOVE:

int curScrollX = getScrollX();

int dis_x = (int) (ev.getX() - point.x);

int expectX = -dis_x + curScrollX;

int finalX = 0;

if (expectX < 0) {

finalX = Math.max(expectX, -leftMenu.getMeasuredWidth());

} else {

finalX = Math.min(expectX, rightMenu.getMeasuredWidth());

}

scrollTo(finalX, 0);

point.x = (int) ev.getX();

break;

case MotionEvent.ACTION_UP:

case MotionEvent.ACTION_CANCEL:

curScrollX = getScrollX();

if (Math.abs(curScrollX) > leftMenu.getMeasuredWidth() >> 1) {

if (curScrollX < 0) {

mScroller.startScroll(curScrollX, 0, -leftMenu.getMeasuredWidth() - curScrollX, 0, 200);

} else {

mScroller.startScroll(curScrollX, 0, leftMenu.getMeasuredWidth() - curScrollX, 0, 200);

}

} else {

mScroller.startScroll(curScrollX, 0, -curScrollX, 0, 200);

}

invalidate();

isleftrightevent = false;

isTestComete = false;

break;

}

}else{

switch (ev.getActionMasked()){

case MotionEvent.ACTION_UP:

isleftrightevent = false;

isTestComete = false;

break;

default:

break;

}

}

return super.dispatchTouchEvent(ev);

}

@Override

public void computeScroll(){

super.computeScroll();

if(!mScroller.computeScrollOffset()){

return;

}

int tempX = mScroller.getCurrX();

scrollTo(tempX, 0);

}

private Point point = new Point();

private static final int TEST_DIS = 20;

private void getEventType(MotionEvent ev){

switch (ev.getActionMasked()){

case MotionEvent.ACTION_DOWN:

point.x = (int)ev.getX();

point.y = (int) ev.getY();

super.dispatchTouchEvent(ev);

break;

case MotionEvent.ACTION_MOVE:

int dX = Math.abs((int)ev.getX() - point.x);

int dY = Math.abs((int)ev.getY() - point.y);

if(dX >= TEST_DIS && dX>dY ){ // 左右滑动

isleftrightevent = true;

isTestComete = true;

point.x = (int)ev.getX();

point.y = (int)ev.getY();

}else if(dY>=TEST_DIS && dY>dX ){ // 上下滑动

isleftrightevent = false;

isTestComete = true;

point.x = (int)ev.getX();

point.y = (int)ev.getY();

}

break;

case MotionEvent.ACTION_UP:

case MotionEvent.ACTION_CANCEL:

super.dispatchTouchEvent(ev);

isleftrightevent = false;

isTestComete = false;

break;

}

}

LeftMenu.java

下面继续看看如何在左侧的目录中添加一个Button。

你需要创建一个LeftMenu类,并扩展Fragment,因此你需要

import android.support.v4.app.Fragment;

如果你不知道如何添加,请看这里:

在下面这段代码之前你需要再新建一个left.xml布局文件,其中添加一个Button1。

@Override

public View onCreateView(LayoutInflater inflater,

@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

View v = inflater.inflate(R.layout.left, container,false);

v.findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

System.out.println("Hello nomasp");

}

});

return v;

}

MainActivity.java

现在你就需要来create它们了。

private MainUI mainUI;

private LeftMenu leftMenu;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

mainUI = new MainUI(this);

setContentView(mainUI);

leftMenu = new LeftMenu();

getSupportFragmentManager().beginTransaction()

.add(MainUI.LEFT_ID, leftMenu).commit();

}

当然了,这里的MainActivity也需要扩展FragmentActivity,也就是要导入android?support?v4.jar,至于如何导入请看前文的导航链接。

当然了,完整的代码你可以从这里Fork:GitHub

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值