抽屉
来源:互联网 发布:云南省卫生网络直报 编辑:程序博客网 时间:2024/04/29 15:44
1.系统提供的抽屉夸奖包的使用
public class MainActivity extends AppCompatActivity implements View.OnDragListener, DrawerLayout.DrawerListener, View.OnClickListener { private DrawerLayout activity_main;//GOOGLE 框架包 private RelativeLayout rl_left;// 左边抽屉 private ListView lv_left;// ListView private List<String> list = new ArrayList<>(); private Button button;//开启左边抽屉 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initList(); initView(); } private void initList() { for (int i = 0; i < 30; i++) { list.add("sasf" + i); } } private void initView() { activity_main = (DrawerLayout) findViewById(R.id.activity_main); rl_left = (RelativeLayout) findViewById(R.id.rl_left); lv_left = (ListView) findViewById(R.id.lv_left); button = (Button) findViewById(R.id.button); lv_left.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list));//给左边菜单写入数据 activity_main.setScrimColor(Color.TRANSPARENT); activity_main.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.LEFT); activity_main.setDrawerListener(this); button.setOnClickListener(this); } //当抽屉正在滑动的时候 @Override public void onDrawerSlide(View drawerView, float slideOffset) { //获取第一个主页面的布局 View mContext = activity_main.getChildAt(0); //获取滑动的抽屉的布局 View draw = drawerView; float scale = 1 - slideOffset; // 意思就是 如果不滑动 scale 是1 , 没有发生变化,滑动后 会缩小 float suofang = 0.8f + scale * 0.2f; //测量 抽屉的宽度 int drawWidth = draw.getMeasuredWidth(); //主页区域 ViewHelper.setScaleX(mContext, suofang); ViewHelper.setScaleY(mContext, suofang); //抽屉区域 ViewHelper.setScaleX(draw, 0.7f + slideOffset * 0.3f); ViewHelper.setScaleY(draw, 0.7f + slideOffset * 0.3f); ViewHelper.setAlpha(draw, 0.6f + slideOffset * 0.4f); //如果两个抽屉的话 可以对每一个抽屉 设置一个TAG 然后判断 ViewHelper.setTranslationX(mContext, drawWidth * slideOffset); } @Override public void onDrawerOpened(View drawerView) { } //当抽屉关闭的时候会调用 @Override public void onDrawerClosed(View drawerView) { activity_main.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.LEFT); } @Override public void onDrawerStateChanged(int newState) { } @Override public boolean onDrag(View v, DragEvent event) { return false; } @Override public void onClick(View v) { activity_main.openDrawer(Gravity.LEFT); activity_main.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, Gravity.LEFT); }}
2.自定义 继承 FrameLayout 布局
public class ZDYChouTi extends FrameLayout { private LinearLayout bottomL; private LinearLayout topL; private boolean isChouTiFlag = false;//抽屉的开关,默认关闭 private boolean isFirst = true;//判断是否第一次进入 private PointF startF = new PointF();//记录 按下 private PointF startF2 = new PointF(); private PointF overF = new PointF();//记录移动后 private int measureWidth = 0;//抽屉宽度 public ZDYChouTi(Context context, AttributeSet attrs) { super(context, attrs); initView(); } private void initView() { //设置底部layout 的属性 bottomL = new LinearLayout(getContext()); topL = new LinearLayout(getContext()); bottomL.setOrientation(LinearLayout.VERTICAL); topL.setOrientation(LinearLayout.VERTICAL); //方便查看设置背景颜色 bottomL.setBackgroundColor(Color.BLACK); topL.setBackgroundColor(Color.RED); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (isFirst) { //将父控件的宽缩小十分之三就是抽屉最大的宽度 measureWidth = (int) (getMeasuredWidth() * 0.7); //bootom_layout就是抽屉界面 FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(measureWidth, FrameLayout.LayoutParams.MATCH_PARENT); bottomL.setLayoutParams(lp); //top_layout是 主界面 FrameLayout.LayoutParams lp2 = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT); topL.setLayoutParams(lp2); //将布局添加到自定义里面 addView(bottomL); addView(topL); } isFirst = false; } public void setBottomView(View v) { v.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)); bottomL.addView(v); } public void setTopView(View v) { v.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)); topL.addView(v); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { startF.x = ev.getX(); startF.y = ev.getY(); startF2.x = ev.getX(); startF2.y = ev.getY(); } else if (ev.getAction() == MotionEvent.ACTION_MOVE) { overF.x = ev.getX(); overF.y = ev.getY(); //水平滑动距离 float disX = (int) (overF.x - startF.x); //垂直滑动距离 float disY = (int) (overF.y - startF.y); //根据正余弦定理来判断 水平滑动或者是垂直滑动, //也就是判断滑动的倾斜度,倾斜度越大,划不动,小则可以拉动抽屉,以y轴为原点; if (Math.abs(disX) / 2 - Math.abs(disY) > 0) { //不做处理 } else { //垂直状态--》抽屉应该关闭 // 通过抽屉的开关来判断上层可否移动 if (!isChouTiFlag) { return super.dispatchTouchEvent(ev); } else { return true; } } //设置一个边界值:防止手指按下出现抽屉抖动的情况 // if (Math.abs(disX) < 10) { // return super.dispatchTouchEvent(ev); // } //根据手指滑动的x轴移动的距离的正负,判断抽屉打开的方向 if (disX > 0) {//大于0 从左往右滑动 //获取到 top_layout的属性 FrameLayout.LayoutParams lp = (LayoutParams) topL.getLayoutParams(); //滑动距离超过最大边距,将最大边距设置给滑动距离 if (lp.leftMargin >= measureWidth) { disX = measureWidth; isChouTiFlag = true;//抽屉开启 } lp.leftMargin = (int) disX;//将移动的距离设置为左边距 lp.rightMargin = (int) -disX; topL.setLayoutParams(lp);//将属性设置给top_layout } else if (disX < 0) { //获取到top_layout的属性 FrameLayout.LayoutParams lp = (LayoutParams) topL.getLayoutParams(); if (lp.leftMargin <= 0) { disX = 0; isChouTiFlag = false; } //滑动前的左边距(topparms.leftMargin)-滑动的距离(Math.abs(disx))=滑动后的左边距 lp.leftMargin = (int) (lp.leftMargin - Math.abs(disX)); lp.rightMargin = -lp.leftMargin; topL.setLayoutParams(lp); startF.x = overF.x;//将移动后的坐标赋值给初始坐标,解决再次移动的问题 } requestLayout();//刷新界面 return true; } else if (ev.getAction() == MotionEvent.ACTION_UP) { int disX = (int) Math.abs(ev.getX() - startF2.x); //区分是点击还是滑动 if (disX > 10) { //以底部linear的宽度的一半为分割线,超过分割线,抽屉自动打开或关闭 FrameLayout.LayoutParams lp = (LayoutParams) topL.getLayoutParams(); if (lp.leftMargin > measureWidth / 2) { lp.leftMargin = measureWidth; lp.rightMargin = -measureWidth; isChouTiFlag = true; } else { //抽屉关闭 lp.leftMargin = 0; lp.rightMargin = 0; isChouTiFlag = false; } topL.setLayoutParams(lp); requestLayout(); return true; } } return super.dispatchTouchEvent(ev); }}
3.系统提供的横向 滑动的 布局 HorizontalScrollView
public class MySlidingMenu extends HorizontalScrollView { // 屏幕宽度 单位:px private int ScreenWidth; // 内容区域宽度 private int contentWidth; // 菜单宽度 private int menuWidth; // 菜单一半的宽度 private int halfmenuWidth; // 菜单的右边距 private int rightPadding; private boolean isMesure; // 是否打开菜单 private boolean isOpen;public MySlidingMenu(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); //用来添加view WindowManager wm = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); //获取手机分辨率 DisplayMetrics outMetrics = new DisplayMetrics(); //获取屏幕的大小 wm.getDefaultDisplay().getMetrics(outMetrics); //widthPixels是宽度方向上的像素点的个数。 ScreenWidth = outMetrics.widthPixels; //自定义属性 TypedArray ta = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MySlidingMenu, defStyle, 0); int count =ta.getIndexCount(); for(int i=0;i<count;i++){ int attr=ta.getIndex(i); Log.e("attr", " "+attr); switch(attr){ case R.styleable.MySlidingMenu_rightPadding: //把dp转化为px rightPadding=ta.getDimensionPixelOffset(attr, (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 200, getResources().getDisplayMetrics())); break; } } } public MySlidingMenu(Context context) { this(context, null, 0); } public MySlidingMenu(Context context, AttributeSet attrs) { this(context, attrs,0);// WindowManager wm = (WindowManager) context// .getSystemService(Context.WINDOW_SERVICE);//// DisplayMetrics outMetrics = new DisplayMetrics();//// wm.getDefaultDisplay().getMetrics(outMetrics);// ScreenWidth = outMetrics.widthPixels; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (!isMesure) { // 避免 Measure方法多次调用 isMesure = true; LinearLayout wrapper = (LinearLayout) getChildAt(0); ViewGroup menu = (ViewGroup) wrapper.getChildAt(0); ViewGroup content = (ViewGroup) wrapper.getChildAt(1);// rightPadding = (int) TypedValue.applyDimension(// TypedValue.COMPLEX_UNIT_DIP, 100, content.getResources()// .getDisplayMetrics()); //屏幕宽度-菜单的右边距 = 菜单的宽度 menuWidth = ScreenWidth - rightPadding; halfmenuWidth = menuWidth / 2; //获取菜单的布局属性获得菜单的宽度 menu.getLayoutParams().width = menuWidth; //主布局的宽度 = 屏幕的宽度 content.getLayoutParams().width = ScreenWidth; } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); if (changed) { //(让ScrollView滚动到(menuWidth, 0)的位置,也就是刚好显示主视图)不带效果的滑动 this.scrollTo(menuWidth, 0); } } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_UP: //就是当前view的左上角相对于母视图的左上角的X轴偏移量。 int scrollX = getScrollX(); if (scrollX > halfmenuWidth) { this.smoothScrollTo(menuWidth, 0); } else { this.smoothScrollTo(0, 0); } return true; } return super.onTouchEvent(ev); } public void openDraw() { if (isOpen) { return; } //让ScrollView滚动到(0,0)的位置 this.smoothScrollTo(0,0); isOpen=true; } public void close() { if (isOpen) { //让ScrollView滚动到(menuWidth,0)的位置 //带效果的滑动 this.smoothScrollTo(menuWidth,0); isOpen=false; } } /* 可以设置一个按钮控制抽屉的开关*/ public void toggle(){ if(isOpen){ close(); }else{ openDraw(); } }}
自定义属性
<?xml version="1.0" encoding="utf-8"?><resources> <attr name="rightPadding" format="dimension" /> <declare-styleable name="MySlidingMenu"> <attr name="rightPadding" /> </declare-styleable></resources>
阅读全文
0 0
- 抽屉
- 抽屉
- 抽屉。
- 抽屉
- 抽屉原则
- 抽屉原理
- 抽屉原理
- 抽屉原理
- 抽屉原理
- 抽屉原理
- 抽屉原理...
- 自定义抽屉
- Android 抽屉
- Android 抽屉
- 抽屉问题
- andrdoi 抽屉
- Android 抽屉
- 抽屉原理
- 安卓中实现如何让下载好的apk自动进入安装界面
- C++ STL string对象操作汇总
- WebStorm支持ES6语法设置
- 用原生HTML5控件实现输入框自动提示(下拉列表补全)功能
- js splice()的用法
- 抽屉
- java缓存范围的分析
- java-FtpClient 503
- URAL 1748. The Most Complex Number(反素数)
- UML类图几种关系的总结
- 《内外兼修:程序员的成长之路》读后感
- C++中构造函数
- hibernate+struts2+spring框架整合
- mysql5.6, mysql5.7什么时候该创建索引?