文档章节

仿微信侧滑菜单slidemenu

o
 osc_5rzx0ke2
发布于 07/01 12:52
字数 1079
阅读 19
收藏 0

精选30+云产品,助力企业轻松上云!>>>

直接上代码 

slidemenu

package com.example.myapplication.customview;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.Scroller;
import android.widget.TextView;

import com.example.myapplication.R;

public class SlideMenu extends ViewGroup implements View.OnClickListener {
    private static final String TAG = "SlideMenu";
    private int function;
    private View contentView;
    private LinearLayout functionView;
    private Scroller scroller;

    float downX = 0;
    float downY = 0;


    public boolean isOpen() {
        return isOpen;
    }

    private boolean isOpen = false;

    private Direction direction = Direction.NONE;
    private float interceptDownX;

    enum Direction {
        LEFT, RIGHT, NONE
    }

    public SlideMenu(Context context) {
        this(context, null);
    }

    public SlideMenu(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SlideMenu(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // 1、添加属性

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlideMenu);
        function = a.getInt(R.styleable.SlideMenu_function, 0);
        a.recycle();


    }


    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        ///2、将View加入进来
        contentView = getChildAt(0);
        functionView = (LinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.slide_item_layout, this, false);
        addView(functionView);
        scroller = new Scroller(getContext());
        initFunctionView();
        Log.d(TAG, "get child count===> " + getChildCount());

    }

    private void initFunctionView() {
        TextView read = functionView.findViewById(R.id.read);
        TextView delete = functionView.findViewById(R.id.delete);
        TextView top = functionView.findViewById(R.id.top);

        delete.setOnClickListener(this);
        read.setOnClickListener(this);
        top.setOnClickListener(this);

        initSlideViewVisible(delete, read, top);

    }


    private void initSlideViewVisible(TextView delete, TextView read, TextView top) {
        final int TOP = 0x03;
        final int DELETE = 0x30;
        final int READ = 0x50;
        final int TOP_DELETE = TOP | DELETE;
        final int TOP_READ = TOP | READ;
        final int READ_DELETE = READ | DELETE;
        final int TOP_READ_DELETE = TOP | READ | DELETE;

        switch (function) {
            case DELETE:
                delete.setVisibility(VISIBLE);
                break;
            case READ:
                read.setVisibility(VISIBLE);
                break;
            case TOP:
                top.setVisibility(VISIBLE);
                break;
            case TOP_DELETE:
                top.setVisibility(VISIBLE);
                delete.setVisibility(VISIBLE);

                break;
            case TOP_READ:
                top.setVisibility(VISIBLE);
                read.setVisibility(VISIBLE);

                break;
            case READ_DELETE:
                read.setVisibility(VISIBLE);
                delete.setVisibility(VISIBLE);
                break;
            case TOP_READ_DELETE:
                top.setVisibility(VISIBLE);
                read.setVisibility(VISIBLE);
                delete.setVisibility(VISIBLE);
                break;
        }

    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int parentHeightSizeSpec = MeasureSpec.getSize(heightMeasureSpec);

        //3、测量第一个孩子

        LayoutParams layoutParams = contentView.getLayoutParams();
        int height = layoutParams.height;

        int heightSpec;
        if (height == LayoutParams.MATCH_PARENT) {
            heightSpec = MeasureSpec.makeMeasureSpec(parentHeightSizeSpec, MeasureSpec.AT_MOST);
        } else if (height == MeasureSpec.EXACTLY) {
            heightSpec = MeasureSpec.makeMeasureSpec(parentHeightSizeSpec, MeasureSpec.EXACTLY);
        } else {
            heightSpec = MeasureSpec.makeMeasureSpec(parentHeightSizeSpec, MeasureSpec.AT_MOST);
        }

        measureChild(contentView, widthMeasureSpec, heightSpec);

        //4、测量第二个孩子

        int measuredHeight = contentView.getMeasuredHeight();

        // 第二个孩子的宽度为最大宽度的3/4
        // 根据具体的孩子来显示具体的宽度

        int visibleCount = 0;
        for (int i = 0; i < functionView.getChildCount(); i++) {
            if (functionView.getChildAt(i).getVisibility() == View.VISIBLE) {
                visibleCount++;
            }
        }
        Log.d(TAG, "child count ==== >" + visibleCount);

        int functionSize = widthMeasureSpec * visibleCount / 4;

        int functionWidth = MeasureSpec.makeMeasureSpec(functionSize, MeasureSpec.EXACTLY);
        int functionHeight = MeasureSpec.makeMeasureSpec(measuredHeight, MeasureSpec.EXACTLY);

        measureChild(functionView, functionWidth, functionHeight);

    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {

        // 5、布局第一个孩子
        int contentLeft = 0;
        int contentTop = 0;
        int contentRight = contentLeft + contentView.getMeasuredWidth();
        int contentBottom = contentView.getMeasuredHeight();
        contentView.layout(contentLeft, contentTop, contentRight, contentBottom);


        int functionTop = 0;
        int functionRight = contentRight + functionView.getMeasuredWidth();

        functionView.layout(contentRight, functionTop, functionRight, contentBottom);

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        //6、计算按下的位置与移动的位置移动当前的视图
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = event.getX();
                downY = event.getY();
                break;
            case MotionEvent.ACTION_MOVE:

                float moveX = event.getX();
                float moveY = event.getY();

                int dx = (int) (moveX - downX);
                if (dx > 0) {
                    direction = Direction.RIGHT;
                } else if (dx < 0) {
                    direction = Direction.LEFT;
                }

                float hasBeenScrolled = getScrollX();

                int resultX = (int) (hasBeenScrolled - dx);
                if (resultX <= 0) {
                    scrollTo(0, 0);
                } else if (resultX > functionView.getMeasuredWidth()) {
                    scrollTo(functionView.getMeasuredWidth(), 0);
                } else {
                    scrollBy(-dx, 0);
                }
                downX = moveX;
                downY = moveY;
                break;
            case MotionEvent.ACTION_UP:
                int scrollX = getScrollX();
                Log.d(TAG, "scroll > >" + scrollX);
                if (isOpen) {
                    //若是打开的
                    if (direction == Direction.LEFT) {
                        open();
                    } else if (direction == Direction.RIGHT) {

                        if (scrollX <= functionView.getMeasuredWidth() * 4 / 5) {
                            close();
                        } else {
                            open();
                        }
                    }
                } else {
                    //默认是关闭的
                    if (direction == Direction.LEFT) {
                        //判断当前滑动的距离
                        if (scrollX >= functionView.getMeasuredWidth() / 5) {
                            open();
                        } else {
                            close();
                        }

                    } else if (direction == Direction.RIGHT) {
                        close();
                    }

                }

                break;
        }

        return true;

    }


    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        //事件冲突

        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                interceptDownX = ev.getX();
                float interceptDownY = ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                float interceptMoveX = ev.getX();
                float interceptMoveY = ev.getY();
                int intercept = (int) (interceptMoveX - interceptDownX);
                if (Math.abs(intercept) > 0) {
                    return true;
                }
                break;
            case MotionEvent.ACTION_UP:
                break;
        }


        return super.onInterceptTouchEvent(ev);

    }

    private void open() {
        scroller.startScroll(getScrollX(), 0, functionView.getMeasuredWidth() - getScrollX(), 0, 500);
        isOpen = true;
        invalidate();
    }


    private void close() {
        scroller.startScroll(getScrollX(), 0, -getScrollX(), 0, 500);
        isOpen = false;
        invalidate();
    }

    @Override
    public void onClick(View v) {
        close();
        switch (v.getId()) {
            case R.id.read:
                onItemClickListener.onReadClick();
                break;
            case R.id.delete:
                onItemClickListener.onDeleteClick();
                break;
            case R.id.top:
                onItemClickListener.onTopClick();
                break;
        }
    }

    @Override
    public void computeScroll() {
        super.computeScroll();

        if (scroller.computeScrollOffset()) {
            int currX = scroller.getCurrX();
            scrollTo(currX, 0);
            invalidate();
        }
    }


    // 通过接口将事件传递出去
    private onItemClickListener onItemClickListener;

    public void setOnItemClickListener(SlideMenu.onItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    public interface onItemClickListener {
        void onDeleteClick();

        void onReadClick();

        void onTopClick();
    }
}

属性 

<declare-styleable name="SlideMenu">
    <attr name="function" format="flags">
        <flag name="delete" value="0x30" />
        <flag name="read" value="0x50" />
        <flag name="top" value="0x03" />
    </attr>
</declare-styleable>

 

布局

activity_main

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <com.example.myapplication.customview.SlideMenu
        android:id="@+id/slide_menu"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:function="top|delete">

        <TextView
            android:id="@+id/content_tv"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:background="#dddddd"
            android:gravity="center"
            android:text="群成员"
            android:textColor="#000"
            android:textSize="20sp" />
    </com.example.myapplication.customview.SlideMenu>

</LinearLayout>

slide_item_layout.xml

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

    <TextView
        android:id="@+id/read"
        android:layout_width="0dp"
        android:visibility="gone"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="#008800"
        android:gravity="center"
        android:text="已读"
        android:textColor="#fff"
        android:textSize="20dp" />

    <TextView
        android:id="@+id/top"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="#666666"
        android:visibility="gone"
        android:gravity="center"
        android:text="置顶"
        android:textColor="#fff"
        android:textSize="20dp" />

    <TextView
        android:visibility="gone"
        android:id="@+id/delete"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="#ff0000"
        android:gravity="center"
        android:text="删除"
        android:textColor="#fff"
        android:textSize="20dp" />
</LinearLayout>

MainActivity

 

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.example.myapplication.customview.FlowLayout;
import com.example.myapplication.customview.SlideMenu;
import com.example.myapplication.customview.TextBanner;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    private String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        SlideMenu slideMenu = findViewById(R.id.slide_menu);
        slideMenu.setOnItemClickListener(new SlideMenu.onItemClickListener() {
            @Override
            public void onDeleteClick() {
                Log.d(TAG, "ON DELETE");
            }

            @Override
            public void onReadClick() {
                Log.d(TAG, "ON READ");
            }

            @Override
            public void onTopClick() {
                Log.d(TAG, "ON TOP");

            }
        });
    }
}

效果图  

 

o
粉丝 0
博文 59
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
Android SlidingMenu 使用详解

1、在Activity中通过SlidingMenu构造方法,直接设置侧滑菜单 package com.zhy.zhyslidemenudemo; import android.app.Activity; import android.os.Bundle; import com.jeremyfeinstein.slid......

今日竹石
2015/01/06
325
0
仿微信侧滑菜单slidemenu

直接上代码 slidemenu 属性 布局 activity_main slideitemlayout.xml MainActivity 效果图

空山新雨后来秋
06/30
0
0
我的第一个开源android app[哇靠百科]

原文地址:http://blog.wakao.me/index.php/archives/384.html 哇靠百科 [访问github地址][1] 那么,这是个什么样的App呢? 哇靠百科是一个聚合笑话、文章、美图的娱乐App。 数据来自,糗事百...

bobo_ll
2014/04/19
597
5
iOS 侧边菜单 - YiSlideMenu

SlideMenu,简洁的侧边菜单,清爽风格。YiSlideView 是用 UIScrollView 实现的侧边菜单,左菜单、右菜单以及中间视图加在UIScrollView上。 使用方法...

oschina2000
2015/03/10
1.4K
0
一个小应用,欢迎多提宝贵意见,谢谢~~

做了个答题类的小应用,欢迎大家多提宝贵意见,谢谢~~ 1、随便P了个启动界面及slidemenu菜单: 2、答题等相关界面: 3、查看历史与收藏:历史与收藏的字体颜色会不一样,这里没有截图出来 = ...

贺路的路
2013/08/14
4.7K
65

没有更多内容

加载失败,请刷新页面

加载更多

Kafka如何在千万级别时优化JVM GC问题?

大家都知道Kafka是一个高吞吐的消息队列,是大数据场景首选的消息队列,这种场景就意味着发送单位时间消息的量会特别的大,那既然如此巨大的数据量,kafka是如何支撑起如此庞大的数据量的分发...

hummerstudio
06/18
6
0
我打赌!90%程序员都破解不了这个粽子,不信你试!

放假了 各位读者朋友们,马上就是端午小长假啦,开心激动有木有? 新的故事文章还在创作中,写了初稿感觉不太满意又推倒重来。其实写故事还是挺难的,读者可能第一次第二次有新鲜感,写多了就...

轩辕之风
06/24
20
0
如何删库跑路?教你使用Binlog日志恢复误删的MySQL数据

前言 “删库跑路”是程序员经常谈起的话题,今天,我就要教大家如何删!库!跑!路! 开个玩笑,今天文章的主题是如何使用Mysql内置的Binlog日志对误删的数据进行恢复,读完本文,你能够了解...

后端技术漫谈
01/14
22
0
PHP设计模式之代理模式

PHP设计模式之代理模式 代理人这个职业在中国有另外一个称呼,房产经济人、保险经济人,其实这个职业在国外都是叫做房产代理或者保险代理。顾名思义,就是由他们来帮我们处理这些对我们大部分...

硬核项目经理
2019/09/23
7
0
Redis的复制模式

Redis的复制功能分为同步(sync)和命令传播(command propagate)两个操作。 同步 同步操作用于将从服务器的数据库状态更新至主服务器当前所处的数据库状态。 1. 旧版本的执行步骤 从服务器...

osc_s9cni3go
35分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部