我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android实现自定义滑动式抽屉效果菜单

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android实现自定义滑动式抽屉效果菜单

在Andoird使用Android自带的那些组件,像SlidingDrawer和DrawerLayout都是抽屉效果的菜单,但是在项目很多要实现的功能都收到Android这些自带组件的限制,导致很难完成项目的需求,自定义的组件,各方面都在自己的控制之下,从而根据需求做出调整。想要实现好的效果,基本上都的基于Android的OnTouch事件自己实现响应的功能。
首先,给大家先看一下整体的效果:

滑动的加速度效果都是有的,具体的体验,只能安装后才能查看。
接下来,看代码:
代码从MainActivity延伸出了2个类:MainController和MainView,MainController来处理控制层、MainView来操作展示层。
主要代码:
MainActivity的代码:


package com.example.wz;
import com.example.wz.controller.MainController;
import com.example.wz.util.MyLog;
import com.example.wz.view.MainView;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
public class MainActivity extends Activity {
 public MyLog log = new MyLog(this, true);
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  log.e("欢迎你加入测试项目.");
  link();
 }
 public MainController mainController;
 public MainView mainView;
 private void link() {
  this.mainController = new MainController(this);
  this.mainView = new MainView(this);
  this.mainController.thisView = this.mainView;
  this.mainView.thisController = this.mainController;
  this.mainView.initViews();
 }
 @Override
 public boolean onTouchEvent(MotionEvent event) {
  super.onTouchEvent(event);
  return mainController.onTouchEvent(event);
 }
}

MainController的代码:


package com.example.wz.controller;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import com.example.wz.MainActivity;
import com.example.wz.util.MyLog;
import com.example.wz.util.OpenLooper;
import com.example.wz.util.OpenLooper.LoopCallback;
import com.example.wz.view.MainView;
public class MainController {
 public MyLog log = new MyLog(this, true);
 public MainActivity mainActivity;
 public MainController thisController;
 public MainView thisView;
 public GestureDetector mGesture;
 public MainController(MainActivity mainActivity) {
  this.mainActivity = mainActivity;
  this.thisController = this;
  mGesture = new GestureDetector(mainActivity, new GestureListener());
  openLooper = new OpenLooper();
  openLooper.createOpenLooper();
  loopCallback = new ListLoopCallback(openLooper);
  openLooper.loopCallback = loopCallback;
 }
 public class TouchStatus {
  public int None = 4, Down = 1, Horizontal = 2, Vertical = 3, Up = 4;// LongPress = 5
  public int state = None;
 }
 public TouchStatus touchStatus = new TouchStatus();
 public class BodyStatus {
  public int Fixed = 0, Dragging = 1, Homing = 2, FlingHoming = 3, BoundaryHoming = 4;
  public int state = Fixed;
 }
 public BodyStatus bodyStatus = new BodyStatus();
 public class DrawStatus {
  public int Closed = 0, Open = 1, GoClosing = 2, GoOpening = 3;
  public int state = Closed;
 }
 public DrawStatus drawStatus = new DrawStatus();
 public class AreaStatus {
  public int A = 0, B = 1;
  public int state = A;
 }
 public AreaStatus areaStatus = new AreaStatus();
 public float touch_pre_x;
 public float touch_pre_y;
 public float currentTranslateX;
 public boolean onTouchEvent(MotionEvent event) {
  int action = event.getAction();
  float x = event.getX();
  float y = event.getY();
  if (action == MotionEvent.ACTION_DOWN) {
   this.touch_pre_x = x;
   this.touch_pre_y = y;
   if (touchStatus.state == touchStatus.None) {
    touchStatus.state = touchStatus.Down;
    log.e("Down ");
    if (x > thisView.maxTranslateX) {
     areaStatus.state = areaStatus.B;
    } else if (x <= thisView.maxTranslateX) {
     areaStatus.state = areaStatus.A;
    }
   }
  } else if (action == MotionEvent.ACTION_MOVE) {
   float Δy = (y - touch_pre_y);
   float Δx = (x - touch_pre_x);
   if (touchStatus.state == touchStatus.Down) {
    if (Δx * Δx + Δy * Δy > 400) {
     if (Δx * Δx > Δy * Δy) {
      touchStatus.state = touchStatus.Horizontal;
     } else {
      touchStatus.state = touchStatus.Vertical;
     }
     touch_pre_x = x;
     touch_pre_y = y;
     log.e("ACTION_MOVE ");
    }
   } else if (touchStatus.state == touchStatus.Horizontal) {
    currentTranslateX += Δx;
    this.touch_pre_x = x;
    this.touch_pre_y = y;
    if (currentTranslateX - thisView.maxTranslateX <= 0 && currentTranslateX >= 0) {
     setPosition();
    }
    log.e("Horizontal");
    bodyStatus.state = bodyStatus.Dragging;
   } else if (touchStatus.state == touchStatus.Vertical) {
    log.e("Vertical");
    bodyStatus.state = bodyStatus.Dragging;
   }
  } else if (action == MotionEvent.ACTION_UP) {
   log.e("ACTION_UP");
   if (bodyStatus.state == bodyStatus.Dragging) {
    if (touchStatus.state == touchStatus.Horizontal) {
     bodyStatus.state = bodyStatus.Homing;
     openLooper.start();
    } else if (touchStatus.state == touchStatus.Vertical) {
     if (drawStatus.state == drawStatus.Open && areaStatus.state == areaStatus.B) {
      bodyStatus.state = bodyStatus.Homing;
      drawStatus.state = drawStatus.GoClosing;
      openLooper.start();
     }
    }
   } else if (touchStatus.state == touchStatus.Down && areaStatus.state == areaStatus.B) {
    bodyStatus.state = bodyStatus.Homing;
    drawStatus.state = drawStatus.GoClosing;
    openLooper.start();
   }
   touchStatus.state = touchStatus.Up;
  }
  mGesture.onTouchEvent(event);
  return true;
 }
 class GestureListener extends SimpleOnGestureListener {
  @Override
  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
   if (velocityX * velocityX + velocityY * velocityY > 250000) {
    if (velocityX * velocityX > velocityY * velocityY) {
     log.e("velocityX--" + velocityX);
     if (drawStatus.state == drawStatus.Closed && velocityX < 0) {
     } else if (drawStatus.state == drawStatus.Open && velocityX > 0) {
     } else {
      dxSpeed = velocityX;
      bodyStatus.state = bodyStatus.FlingHoming;
      openLooper.start();
     }
    } else {
     log.e("velocityY");
    }
   }
   return true;
  }
  public void onLongPress(MotionEvent event) {
  }
  public boolean onDoubleTap(MotionEvent event) {
   return false;
  }
  public boolean onDoubleTapEvent(MotionEvent event) {
   return false;
  }
  public boolean onSingleTapUp(MotionEvent event) {
   return false;
  }
  @Override
  public boolean onSingleTapConfirmed(MotionEvent event) {
   return false;
  }
  public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
   return false;
  }
 }
 public void setPosition() {
  thisView.v1.setTranslationX(currentTranslateX - thisView.maxTranslateX);
  thisView.v2.setTranslationX(Math.abs(currentTranslateX));
 }
 float transleteSpeed = 3f;
 OpenLooper openLooper = null;
 LoopCallback loopCallback = null;
 public class ListLoopCallback extends LoopCallback {
  public ListLoopCallback(OpenLooper openLooper) {
   openLooper.super();
  }
  @Override
  public void loop(double ellapsedMillis) {
   if (bodyStatus.state == bodyStatus.Homing) {
    hommingView((float) ellapsedMillis);
   } else if (bodyStatus.state == bodyStatus.FlingHoming) {
    flingHomingView((float) ellapsedMillis);
   }
  }
 }
 public float ratio = 0.0008f;
 public void flingHomingView(float ellapsedMillis) {
  float distance = (float) ellapsedMillis * transleteSpeed;
  boolean isStop = false;
  if (drawStatus.state == drawStatus.Closed) {
   drawStatus.state = drawStatus.GoOpening;
  } else if (drawStatus.state == drawStatus.Open) {
   drawStatus.state = drawStatus.GoClosing;
  }
  if (drawStatus.state == drawStatus.GoClosing) {
   this.currentTranslateX -= distance;
   if (this.currentTranslateX <= 0) {
    this.currentTranslateX = 0;
    drawStatus.state = drawStatus.Closed;
    isStop = true;
    log.e("-------------1");
   }
  } else if (drawStatus.state == drawStatus.GoOpening) {
   this.currentTranslateX += distance;
   if (this.currentTranslateX >= thisView.maxTranslateX) {
    this.currentTranslateX = thisView.maxTranslateX;
    drawStatus.state = drawStatus.Open;
    isStop = true;
    log.e("-------------2");
   }
  }
  setPosition();
  if (isStop) {
   openLooper.stop();
  }
 }
 public float dxSpeed;
 public void dampenSpeed(long deltaMillis) {
  if (this.dxSpeed != 0.0f) {
   this.dxSpeed *= (1.0f - 0.002f * deltaMillis);
   if (Math.abs(this.dxSpeed) < 50f)
    this.dxSpeed = 0.0f;
  }
 }
 public void hommingView(float ellapsedMillis) {
  float distance = (float) ellapsedMillis * transleteSpeed;
  boolean isStop = false;
  if (drawStatus.state == drawStatus.Closed && this.currentTranslateX < thisView.maxTranslateX / 5) {
   this.currentTranslateX -= distance;
   if (this.currentTranslateX <= 0) {
    this.currentTranslateX = 0;
    drawStatus.state = drawStatus.Closed;
    isStop = true;
   }
  } else if (drawStatus.state == drawStatus.Closed && this.currentTranslateX >= thisView.maxTranslateX / 5) {
   this.currentTranslateX += distance;
   if (this.currentTranslateX >= thisView.maxTranslateX) {
    this.currentTranslateX = thisView.maxTranslateX;
    drawStatus.state = drawStatus.Open;
    isStop = true;
   }
  } else if (drawStatus.state == drawStatus.Open && this.currentTranslateX < thisView.maxTranslateX / 5 * 4) {
   this.currentTranslateX -= distance;
   if (this.currentTranslateX <= 0) {
    this.currentTranslateX = 0;
    drawStatus.state = drawStatus.Closed;
    isStop = true;
   }
  } else if (drawStatus.state == drawStatus.Open && this.currentTranslateX >= thisView.maxTranslateX / 5 * 4) {
   this.currentTranslateX += distance;
   if (this.currentTranslateX >= thisView.maxTranslateX) {
    this.currentTranslateX = thisView.maxTranslateX;
    drawStatus.state = drawStatus.Open;
    isStop = true;
   }
  } else if (drawStatus.state == drawStatus.GoClosing) {
   this.currentTranslateX -= distance;
   if (this.currentTranslateX <= 0) {
    this.currentTranslateX = 0;
    drawStatus.state = drawStatus.Closed;
    isStop = true;
   }
  }
  setPosition();
  if (isStop) {
   openLooper.stop();
   log.e("looper stop...");
  }
 }
}

MainView的代码:


package com.example.wz.view;
import android.graphics.Color;
import android.util.DisplayMetrics;
import android.view.ViewGroup.LayoutParams;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.example.wz.MainActivity;
import com.example.wz.R;
import com.example.wz.controller.MainController;
import com.example.wz.util.MyLog;
public class MainView {
 public MyLog log = new MyLog(this, true);
 public MainActivity mainActivity;
 public MainController thisController;
 public MainView thisView;
 public MainView(MainActivity mainActivity) {
  this.mainActivity = mainActivity;
  this.thisView = this;
 }
 public DisplayMetrics displayMetrics;
 public float screenWidth;
 public float screenHeight;
 public float density;
 public float maxTranslateX;
 public RelativeLayout maxView;
 public RelativeLayout v1;
 public RelativeLayout v2;
 public void initViews() {
  this.displayMetrics = new DisplayMetrics();
  this.mainActivity.getWindowManager().getDefaultDisplay().getMetrics(this.displayMetrics);
  this.screenHeight = this.displayMetrics.heightPixels;
  this.screenWidth = this.displayMetrics.widthPixels;
  this.density = this.displayMetrics.density;
  this.maxTranslateX = this.screenWidth * 0.8f;
  this.mainActivity.setContentView(R.layout.activity_main);
  this.maxView = (RelativeLayout) this.mainActivity.findViewById(R.id.maxView);
  v1 = new RelativeLayout(mainActivity);
  v1.setBackgroundColor(Color.RED);
  RelativeLayout.LayoutParams params1 = new RelativeLayout.LayoutParams((int) this.maxTranslateX, LayoutParams.MATCH_PARENT);
  this.maxView.addView(v1, params1);
  TextView t1 = new TextView(mainActivity);
  t1.setText("left menu bar");
  t1.setTextColor(Color.WHITE);
  v1.addView(t1);
  v1.setTranslationX(0 - this.maxTranslateX);
  v2 = new RelativeLayout(mainActivity);
  v2.setBackgroundColor(Color.parseColor("#0099cd"));
  RelativeLayout.LayoutParams params2 = new RelativeLayout.LayoutParams((int) this.screenWidth, LayoutParams.MATCH_PARENT);
  this.maxView.addView(v2, params2);
  v2.setTranslationX(0);
  TextView t2 = new TextView(mainActivity);
  t2.setText("body content");
  t2.setTextColor(Color.WHITE);
  v2.addView(t2);
 }
}

日志管理类MyLog:


package com.example.wz.util;
import android.util.Log;
public class MyLog {
 public static boolean isGlobalTurnOn = true;
 public boolean isTurnOn = true;
 public String tag = null;
 public MyLog(String tag, boolean isTurnOn) {
  this.tag = tag;
  this.isTurnOn = isTurnOn;
 }
 public MyLog(Object clazz, boolean isTurnOn) {
  this.tag = clazz.getClass().getSimpleName();
  this.isTurnOn = isTurnOn;
 }
 public void v(String message) {
  this.v(this.tag, message);
 }
 public void d(String message) {
  this.d(this.tag, message);
 }
 public void i(String message) {
  this.i(this.tag, message);
 }
 public void w(String message) {
  this.w(this.tag, message);
 }
 public void e(String message) {
  this.e(this.tag, message);
 }
 public void v(String tag, String message) {
  if (isTurnOn && isGlobalTurnOn) {
   Log.v(tag, message);
  }
 }
 public void d(String tag, String message) {
  if (isTurnOn && isGlobalTurnOn) {
   Log.d(tag, message);
  }
 }
 public void i(String tag, String message) {
  if (isTurnOn && isGlobalTurnOn) {
   Log.i(tag, message);
  }
 }
 public void w(String tag, String message) {
  if (isTurnOn && isGlobalTurnOn) {
   Log.w(tag, message);
  }
 }
 public void e(String tag, String message) {
  if (isTurnOn && isGlobalTurnOn) {
   Log.e(tag, message);
  }
 }
}

实现动画效果的核心类OpenLooper:


package com.example.wz.util;
import android.annotation.TargetApi;
import android.os.Build;
import android.os.Handler;
import android.os.SystemClock;
import android.view.Choreographer;
public class OpenLooper {
 public LegacyAndroidSpringLooper legacyAndroidSpringLooper = null;
 public ChoreographerAndroidSpringLooper choreographerAndroidSpringLooper = null;
 public LoopCallback loopCallback = null;
 public void createOpenLooper() {
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
   choreographerAndroidSpringLooper = new ChoreographerAndroidSpringLooper();
  } else {
   legacyAndroidSpringLooper = new LegacyAndroidSpringLooper();
  }
 }
 public void start() {
  if (choreographerAndroidSpringLooper != null) {
   choreographerAndroidSpringLooper.start();
  } else if (legacyAndroidSpringLooper != null) {
   legacyAndroidSpringLooper.start();
  }
 }
 public void stop() {
  if (choreographerAndroidSpringLooper != null) {
   choreographerAndroidSpringLooper.stop();
  } else if (legacyAndroidSpringLooper != null) {
   legacyAndroidSpringLooper.stop();
  }
 }
 public class LoopCallback {
  public void loop(double ellapsedMillis) {
  }
 }
 public void loop(double ellapsedMillis) {
  if (this.loopCallback != null) {
   this.loopCallback.loop(ellapsedMillis);
  }
 }
 public class LegacyAndroidSpringLooper {
  public Handler mHandler;
  public Runnable mLooperRunnable;
  public boolean mStarted;
  public long mLastTime;
  public LegacyAndroidSpringLooper() {
   initialize(new Handler());
  }
  public void initialize(Handler handler) {
   mHandler = handler;
   mLooperRunnable = new Runnable() {
    @Override
    public void run() {
     if (!mStarted) {
      return;
     }
     long currentTime = SystemClock.uptimeMillis();
     loop(currentTime - mLastTime);
     mHandler.post(mLooperRunnable);
    }
   };
  }
  public void start() {
   if (mStarted) {
    return;
   }
   mStarted = true;
   mLastTime = SystemClock.uptimeMillis();
   mHandler.removeCallbacks(mLooperRunnable);
   mHandler.post(mLooperRunnable);
  }
  public void stop() {
   mStarted = false;
   mHandler.removeCallbacks(mLooperRunnable);
  }
 }
 @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
 public class ChoreographerAndroidSpringLooper {
  public Choreographer mChoreographer;
  public Choreographer.FrameCallback mFrameCallback;
  public boolean mStarted;
  public long mLastTime;
  public ChoreographerAndroidSpringLooper() {
   initialize(Choreographer.getInstance());
  }
  public void initialize(Choreographer choreographer) {
   mChoreographer = choreographer;
   mFrameCallback = new Choreographer.FrameCallback() {
    @Override
    public void doFrame(long frameTimeNanos) {
     if (!mStarted) {
      return;
     }
     long currentTime = SystemClock.uptimeMillis();
     loop(currentTime - mLastTime);
     mLastTime = currentTime;
     mChoreographer.postFrameCallback(mFrameCallback);
    }
   };
  }
  public void start() {
   if (mStarted) {
    return;
   }
   mStarted = true;
   mLastTime = SystemClock.uptimeMillis();
   mChoreographer.removeFrameCallback(mFrameCallback);
   mChoreographer.postFrameCallback(mFrameCallback);
  }
  public void stop() {
   mStarted = false;
   mChoreographer.removeFrameCallback(mFrameCallback);
  }
 }
}

转载来自:http://blog.csdn.net/qxs965266509

源码下载:抽屉效果

您可能感兴趣的文章:Android制作微信app顶部menu菜单(ActionBar)Android仿今日头条APP实现下拉导航选择菜单效果Android App中DrawerLayout抽屉效果的菜单编写实例Android界面设计(APP设计趋势 左侧隐藏菜单右边显示content)Android实现顶部导航菜单左右滑动效果Android滑动优化高仿QQ6.0侧滑菜单(滑动优化)android RecyclerView侧滑菜单,滑动删除,长按拖拽,下拉刷新上拉加载Android仿微信滑动弹出编辑、删除菜单效果、增加下拉刷新功能Android利用滑动菜单框架实现滑动菜单效果Android实现美团APP的底部滑动菜单


免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Android实现自定义滑动式抽屉效果菜单

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android实现自定义滑动式抽屉效果菜单

在Andoird使用Android自带的那些组件,像SlidingDrawer和DrawerLayout都是抽屉效果的菜单,但是在项目很多要实现的功能都收到Android这些自带组件的限制,导致很难完成项目的需求,自定义的组件,各方面都在自
2022-06-06

Android自定义控件简单实现侧滑菜单效果

侧滑菜单在很多应用中都会见到,最近QQ5.0侧滑还玩了点花样~~对于侧滑菜单,一般大家都会自定义ViewGroup,然后隐藏菜单栏,当手指滑动时,通过Scroller或者不断的改变leftMargin等实现;多少都有点复杂,完成以后还需要对
2022-06-06

Android 抽屉效果的导航菜单实现代码实例

看了很多应用,觉得这种侧滑的抽屉效果的菜单很好。不用切换到另一个页面,也不用去按菜单的硬件按钮,直接在界面上一个按钮点击,菜单就滑出来,而且感觉能放很多东西。 关于实现,搜索了一下,有如下两种: 1.用SlidingDrawer:http:
2022-06-06

Android自定义ViewGroup实现侧滑菜单

这篇文章主要为大家详细介绍了Android如何通过自定义ViewGroup实现侧滑菜单,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
2023-01-05

Android自定义HorizontalScrollView实现qq侧滑菜单

今天看了鸿洋_大神在慕课网讲的qq5.0侧滑菜单。学了不少的知识,同时也佩服鸿洋_大神思路的清晰。 看了教程课下也自己实现了一下。代码几乎完全相同 别喷我啊。。没办法 o(︶︿︶)o 唉像素不好 没办法 找不到好的制作gif的软件。 我们
2022-06-06

怎么在Android中通过自定义View实现一个抽屉效果

怎么在Android中通过自定义View实现一个抽屉效果?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Android 自定义View实现抽屉效果说明这个自定义V
2023-05-31

Android自定义控件实现滑动开关效果

自定义开关控件 Android自定义控件一般有三种方式 1、继承Android固有的控件,在Android原生控件的基础上,进行添加功能和逻辑。 2、继承ViewGroup,这类自定义控件是可以往自己的布局里面添加其他的子控件的。
2022-06-06

Android自定义VIew实现卫星菜单效果浅析

一 概述: 最近一直致力于Android自定义VIew的学习,主要在看《android群英传》,还有CSDN博客鸿洋大神和wing大神的一些文章,写的很详细,自己心血来潮,学着写了个实现了类似卫星效果的一个自定义的View,分享到博客上,
2022-06-06

Android中自定义view实现侧滑效果

效果图:看网上的都是两个view拼接,默认右侧的不显示,水平移动的时候把右侧的view显示出来。但是看最新版QQ上的效果不是这样的,但给人的感觉却很好,所以献丑来一发比较高仿的。 知识点: 1、ViewDragHelper 的用法; 2、
2022-06-06

Android实现顶部导航菜单左右滑动效果

本文给大家介绍在Android中如何实现顶部导航菜单左右滑动效果,具体内容如下 第一种解决方案: 实现原理是使用android-support-v4.jar包中ViewPager控件,在ViewPager控件中设置流布局,再在流布局中设置
2022-06-06

Android怎么自定义View实现竖向滑动回弹效果

这篇文章主要介绍“Android怎么自定义View实现竖向滑动回弹效果”,在日常操作中,相信很多人在Android怎么自定义View实现竖向滑动回弹效果问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Andro
2023-06-30

Android实现自定义的卫星式菜单(弧形菜单)详解

一、前言 Android 实现卫星式菜单也叫弧形菜单,主要要做的工作如下:1.动画的处理2.自定义ViewGroup来实现卫星式菜单View(1)自定义属性 a. 在attrs.xml中定义属性 b. 在布局中使用自
2022-06-06

Android中怎么通过自定义View 实现QQ侧滑菜单

这期内容当中小编将会给大家带来有关Android中怎么通过自定义View 实现QQ侧滑菜单,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。布局代码
2023-05-30

Android如何自定View实现滑动验证效果

本篇内容主要讲解“Android如何自定View实现滑动验证效果”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android如何自定View实现滑动验证效果”吧!效果图自定义属性代码
2023-06-22

通过在Android中自定义StickinessView实现一个粘性滑动效果

这篇文章给大家介绍通过在Android中自定义StickinessView实现一个粘性滑动效果,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。一、首先,要确定HeadLayout什么时候可以拦截事件,那么就要确定List
2023-05-31

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录