ios + Android 底部拖拉菜单

这个简易 的底部拖拉菜单没什么工作量,这里氷分析了,直接上代码,距离属性没剥离出来,不过很简单,各位大神用到的时候,自己扩展吧

 

代码如下:

 

@interface ViewController ()

@property(nonatomic,strong) UIView* bottomView;

@property(nonatomic, strong) NSLayoutConstraint *bottomHeightCons;

@property(nonatomic,assign) CGPoint startPos;

@property(nonatomic,assign) CGPoint endPos;

@property(nonatomic,assign) CGPoint originPos;

@property(nonatomic,assign) BOOL bIsDirectionDowm;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    [self initView];
    
}

-(void) initView{

    self.bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height - 100,
                                                               self.view.frame.size.width, 300)];
    self.bottomView.backgroundColor = [UIColor greenColor];
    self.bottomView.translatesAutoresizingMaskIntoConstraints = NO;
    
    UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(100, self.bottomView.frame.size.height - 80, 160, 40)];
    label.text = @"底部隐藏菜单";
    [self.bottomView addSubview:label];
    
    
    [self.view addSubview:self.bottomView];
    
    self.originPos = self.bottomView.center;
    
    self.bIsDirectionDowm = false;
}

-(void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    UITouch *touch = [touches anyObject];
    self.startPos = [touch locationInView:self.view];
    

}

-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    
    UITouch *touch = [touches anyObject];
    CGPoint curP = [touch locationInView:self.view];

    
    if(curP.y - self.startPos.y <= 0 && curP.y - self.startPos.y >= -200){      //向上滑
        
        if(self.bIsDirectionDowm) return;
        self.bottomView.center = CGPointMake(self.bottomView.center.x, self.originPos.y + ( curP.y - self.startPos.y));
        
    }else if(curP.y - self.startPos.y > 0 && curP.y - self.startPos.y <= 100){ //向下滑动
    
        if(!self.bIsDirectionDowm) return;
        self.bottomView.center = CGPointMake(self.bottomView.center.x, self.originPos.y - 100 + ( curP.y - self.startPos.y));
    }
    
}

//当手指离开屏幕时调用
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    UITouch *touch = [touches anyObject];
    self.endPos = [touch locationInView:self.view];

    if(self.endPos.y - self.startPos.y <= 0 && self.endPos.y - self.startPos.y >= -100){  //向上滑动
    
        
        [UIView animateWithDuration:0.3 animations:^{
            
            self.bottomView.center = CGPointMake(self.bottomView.center.x, self.view.frame.size.height - self.bottomView.frame.size.height / 2);
            self.bIsDirectionDowm = true;
            
        }];
        
    }
    
    else if(self.endPos.y - self.startPos.y >= 0 && self.endPos.y - self.startPos.y <= 100){
    
        
        [UIView animateWithDuration:0.1 animations:^{
            
            self.bottomView.center = CGPointMake(self.bottomView.center.x, self.originPos.y);
            self.bIsDirectionDowm = false;
            
        }];
        
    }

}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

 

 

Android 部分:参考:https://www.jb51.net/article/117780.htm

package com.sensetime.armap.widgt;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Scroller;

import androidx.annotation.Nullable;

import com.sensetime.armap.R;
import com.sensetime.libcenter.utils.LogUtils;

/**
 * Create By 刘铁柱
 * Create Date 2019-09-11
 * Sensetime@Copyright
 * Des: 垂直可伸缩菜单
 */
public class ElasticLayout extends LinearLayout {

    LinearLayout bottomBar,bottomContent;
    private Scroller mScroller;
    public ElasticLayout(Context context) {
        super(context);
    }

    public ElasticLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mScroller = new Scroller(context);
    }

    public ElasticLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mScroller = new Scroller(context);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        bottomContent = findViewById(R.id.bottomContent);
        bottomBar = findViewById(R.id.bottombar);
        findViewById(R.id.bottom_btn).setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View view) {
                LogUtils.print(48,"");
            }
        });

        findViewById(R.id.bottom_btn2).setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View view) {
                LogUtils.print(56,"");
            }
        });

    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        bottomBar.layout(0, getMeasuredHeight() - bottomBar.getMeasuredHeight(), getMeasuredWidth(), getMeasuredHeight());
        bottomContent.layout(0, getMeasuredHeight(), getMeasuredWidth(), bottomBar.getBottom() + bottomContent.getMeasuredHeight());
    }

    float downX,downY;
    int scrollOffset;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                downX = (int) event.getX();
                downY = (int) event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                int endY = (int) event.getY();
                int dy = (int) (endY - downY);
                int toScroll = getScrollY() - dy;
                if(toScroll < 0){
                    toScroll = 0;
                } else if(toScroll > bottomContent.getMeasuredHeight()){
                    toScroll = bottomContent.getMeasuredHeight();
                }
                scrollTo(0, toScroll);
                downY = (int) event.getY();
                break;
            case MotionEvent.ACTION_UP:
                scrollOffset = getScrollY();
                if(scrollOffset > bottomContent.getMeasuredHeight() / 2){
                    expendBottom();
                } else {
                    closeBottom();
                }
                break;
        }

        return true;
    }

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) { // 计算新位置,并判断上一个滚动是否完成。
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            invalidate();// 再次调用computeScroll。
        }
    }

    private void expendBottom(){
        int dy = bottomContent.getMeasuredHeight() - scrollOffset;
        mScroller.startScroll(getScrollX(), getScrollY(), 0, dy, 500);
        invalidate();
    }

    private void closeBottom(){
        int dy = 0 - scrollOffset;
        mScroller.startScroll(getScrollX(), getScrollY(), 0, dy, 500);
        invalidate();
    }
}

 

布局文件:

<?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">

    <com.sensetime.armap.widgt.ElasticLayout
        android:orientation="vertical"
        android:layout_alignParentBottom="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <LinearLayout
            android:id="@+id/bottombar"
            android:orientation="vertical"
            android:background="@color/colorAccent"
            android:layout_width="match_parent"
            android:layout_height="50dp">

            <Button
                android:id="@+id/bottom_btn"
                android:text="test_click"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

        </LinearLayout>

        <LinearLayout
            android:id="@+id/bottomContent"
            android:orientation="vertical"
            android:background="@color/colorPrimaryDark"
            android:layout_width="match_parent"
            android:layout_height="200dp">

            <Button
                android:id="@+id/bottom_btn2"
                android:text="test_click2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

        </LinearLayout>
    </com.sensetime.armap.widgt.ElasticLayout>



</LinearLayout>
 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值