欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

基于Android实现仿QQ5.0侧滑

程序员文章站 2023-12-17 15:32:46
本课程将带领大家通过自定义控件实现qq5.0侧滑菜单,课程将循序渐进,首先实现最普通的侧滑菜单,然后引入属性动画与拖动菜单效果相结合,最终实现qq5.0侧滑菜单效果。通过本...

本课程将带领大家通过自定义控件实现qq5.0侧滑菜单,课程将循序渐进,首先实现最普通的侧滑菜单,然后引入属性动画与拖动菜单效果相结合,最终实现qq5.0侧滑菜单效果。通过本课程大家会对侧滑菜单有更深层次的了解,通过自定义控件和属性动画打造千变万化的侧滑菜单效果

效果图如下所示:

基于Android实现仿QQ5.0侧滑基于Android实现仿QQ5.0侧滑

package com.example;
import android.os.bundle;
import android.support.v7.app.actionbaractivity;
import android.view.view;
public class mainactivity extends actionbaractivity {
  private slidingmenu mmenu;
  @override
  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_main);
    mmenu = (slidingmenu) findviewbyid(r.id.id_menu);
  }
  public void togglemenu(view view)
  {
    mmenu.toggle();
  }
} 
package com.example;
import android.app.activity;
import android.content.context;
import android.graphics.bitmap;
import android.graphics.rect;
import android.util.displaymetrics;
import android.view.view;
import android.view.windowmanager;
/**
 * created by tuhao-pc on 2015/12/28.
 * 获取屏幕相关的辅助类
 */
public class screenutils {
  private screenutils() {
  }
  /**
   *获取屏幕的高度
   * @param context
   * @return
   */
  public static int getscreenwidth(context context){
    windowmanager wm = (windowmanager) context.getsystemservice(context.window_service);
    displaymetrics outmetrics = new displaymetrics();
    wm.getdefaultdisplay().getmetrics(outmetrics);
    return outmetrics.widthpixels;
  }
  /**
   * 获取屏幕的高度
   * @param context
   * @return
   */
  public static int getscreenheight(context context){
    windowmanager wm = (windowmanager) context.getsystemservice(context.window_service);
    displaymetrics outmetrics = new displaymetrics();
    wm.getdefaultdisplay().getmetrics(outmetrics);
    return outmetrics.heightpixels;
  }
  /**
   * 获取手机状态栏的状态
   * @param context
   * @return
   */
  public static int getstatusheight(context context){
    int statusheight = -1;
    class<?> clazz = null;
    try {
      clazz = class.forname("com.android.internal.r$dimen");
      object object = clazz.newinstance();
      int height = integer.parseint(clazz.getfield("status_bar_height").get(object).tostring());
      statusheight = context.getresources().getdimensionpixelsize(height);
    } catch (classnotfoundexception e) {
      e.printstacktrace();
    } catch (nosuchfieldexception e) {
      e.printstacktrace();
    } catch (instantiationexception e) {
      e.printstacktrace();
    } catch (illegalaccessexception e) {
      e.printstacktrace();
    }
    return statusheight;
  }
  /**
   * 获取当前屏幕截图,包含状态栏
   *
   * @param activity
   * @return
   */
  public static bitmap snapshotwithstatusbar(activity activity)
  {
    view view = activity.getwindow().getdecorview();
    view.setdrawingcacheenabled(true);
    view.builddrawingcache();
    bitmap bmp = view.getdrawingcache();
    int width = getscreenwidth(activity);
    int height = getscreenheight(activity);
    bitmap bp = null;
    bp = bitmap.createbitmap(bmp, 0, 0, width, height);
    view.destroydrawingcache();
    return bp;
  }
  /**
   * 获取当前屏幕截图,不包含状态栏
   *
   * @param activity
   * @return
   */
  public static bitmap snapshotwithoutstatusbar(activity activity)
  {
    view view = activity.getwindow().getdecorview();
    view.setdrawingcacheenabled(true);
    view.builddrawingcache();
    bitmap bmp = view.getdrawingcache();
    rect frame = new rect();
    activity.getwindow().getdecorview().getwindowvisibledisplayframe(frame);
    int statusbarheight = frame.top;
    int width = getscreenwidth(activity);
    int height = getscreenheight(activity);
    bitmap bp = null;
    bp = bitmap.createbitmap(bmp, 0, statusbarheight, width, height
        - statusbarheight);
    view.destroydrawingcache();
    return bp;
  }
} 
package com.example;
import android.content.context;
import android.content.res.typedarray;
import android.util.attributeset;
import android.util.typedvalue;
import android.view.motionevent;
import android.view.viewgroup;
import android.widget.horizontalscrollview;
import android.widget.linearlayout;
import com.nineoldandroids.view.viewhelper;
/**
 * created by tuhao-pc on 2015/12/28.
 */
public class slidingmenu extends horizontalscrollview{
  private int mscreenwidth;
  private int mmenurightpadding;
  private int mmenuwidth;
  private int mhalfmenuwidth;
  private boolean isopen;
  private boolean once;
  private viewgroup mmenu;
  private viewgroup mcontent;
  public slidingmenu(context context) {
    this(context,null);
  }
  public slidingmenu(context context, attributeset attrs) {
    this(context, attrs, 0);
  }
  public slidingmenu(context context, attributeset attrs, int defstyleattr) {
    super(context, attrs, defstyleattr);
    mscreenwidth = screenutils.getscreenwidth(context);
    typedarray a = context.gettheme().obtainstyledattributes(attrs,r.styleable.slidingmenu,defstyleattr,0);
    int count = a.getindexcount();
    for(int i = 0;i < count;i++){
      int attr = a.getindex(i);
      switch (attr){
        case r.styleable.slidingmenu_rightpadding:{
//          默认是50
          mmenurightpadding = a.getdimensionpixelsize(attr, (int) typedvalue.applydimension(typedvalue.complex_unit_dip,50f,getresources().getdisplaymetrics()));
          break;
        }
      }
    }
    a.recycle();
  }
  @override
  protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {
    /**
     * 显示设置一个宽度
     */
    if(!once){
      linearlayout wrapper = (linearlayout) getchildat(0);
      mmenu = (viewgroup) wrapper.getchildat(0);
      mcontent = (viewgroup) wrapper.getchildat(1);
      mmenuwidth = mscreenwidth - mmenurightpadding;
      mhalfmenuwidth = mmenuwidth/2;
      mmenu.getlayoutparams().width = mmenuwidth;
      mcontent.getlayoutparams().width = mscreenwidth;
    }
    super.onmeasure(widthmeasurespec, heightmeasurespec);
  }
  @override
  protected void onlayout(boolean changed, int l, int t, int r, int b) {
    super.onlayout(changed, l, t, r, b);
    if(changed) {
//      将菜单隐藏
      this.scrollto(mmenuwidth, 0);
      once = true;
    }
  }
  @override
  public boolean ontouchevent(motionevent ev) {
    int action = ev.getaction();
    switch (action){
      // up时,进行判断,如果显示区域大于菜单宽度一半则完全显示,否则隐藏
      case motionevent.action_up:{
        int scrollx = getscrollx();
        if(scrollx > mhalfmenuwidth){
          this.smoothscrollto(mmenuwidth,0);
          isopen = false;
        }
        else{
          this.smoothscrollto(0,0);
          isopen = true;
        }
        return true;
      }
    }
    return super.ontouchevent(ev);
  }
  /**
   * 打开菜单
   */
  public void openmenu()
  {
    if (isopen)
      return;
    this.smoothscrollto(0, 0);
    isopen = true;
  }
  /**
   * 关闭菜单
   */
  public void closemenu()
  {
    if (isopen)
    {
      this.smoothscrollto(mmenuwidth, 0);
      isopen = false;
    }
  }
  /**
   * 切换菜单状态
   */
  public void toggle()
  {
    if (isopen)
    {
      closemenu();
    } else
    {
      openmenu();
    }
  }
  @override
  protected void onscrollchanged(int l, int t, int oldl, int oldt)
  {
    super.onscrollchanged(l, t, oldl, oldt);
    float scale = l * 1.0f / mmenuwidth;
    float leftscale = 1 - 0.3f * scale;
    float rightscale = 0.8f + scale * 0.2f;
    viewhelper.setscalex(mmenu, leftscale);
    viewhelper.setscaley(mmenu, leftscale);
    viewhelper.setalpha(mmenu, 0.6f + 0.4f * (1 - scale));
    viewhelper.settranslationx(mmenu, mmenuwidth * scale * 0.7f);
    viewhelper.setpivotx(mcontent, 0);
    viewhelper.setpivoty(mcontent, mcontent.getheight() / 2);
    viewhelper.setscalex(mcontent, rightscale);
    viewhelper.setscaley(mcontent, rightscale);
  }
}

布局文件和资源文件(xml)

<?xml version="1.0" encoding="utf-8"?>
<linearlayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tu = "http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent">
  <com.example.slidingmenu
    android:id="@+id/id_menu"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@mipmap/img_frame_background"
    tu:rightpadding="20dp">
    <linearlayout
      android:layout_width="wrap_content"
      android:layout_height="fill_parent"
      android:orientation="horizontal" >
      <include layout="@layout/layout_menu" />
      <linearlayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@mipmap/qq" >
        <button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:onclick="togglemenu"
          android:text="切换菜单" />
      </linearlayout>
    </linearlayout>
  </com.example.slidingmenu>
</linearlayout> 
<?xml version="1.0" encoding="utf-8"?>
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="#0000" >
  <linearlayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centervertical="true"
    android:orientation="vertical" >
    <relativelayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content" >
      <imageview
        android:id="@+id/one"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_centervertical="true"
        android:layout_marginleft="20dp"
        android:layout_margintop="20dp"
        android:src="@mipmap/img_1" />
      <textview
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_centervertical="true"
        android:layout_marginleft="20dp"
        android:layout_torightof="@id/one"
        android:text="第1个item"
        android:textcolor="#f0f0f0"
        android:textsize="20sp" />
    </relativelayout>
    <relativelayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content" >
      <imageview
        android:id="@+id/two"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_centervertical="true"
        android:layout_marginleft="20dp"
        android:layout_margintop="20dp"
        android:src="@mipmap/img_2" />
      <textview
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_centervertical="true"
        android:layout_marginleft="20dp"
        android:layout_torightof="@id/two"
        android:text="第2个item"
        android:textcolor="#f0f0f0"
        android:textsize="20sp" />
    </relativelayout>
    <relativelayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content" >
      <imageview
        android:id="@+id/three"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_centervertical="true"
        android:layout_marginleft="20dp"
        android:layout_margintop="20dp"
        android:src="@mipmap/img_3" />
      <textview
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_centervertical="true"
        android:layout_marginleft="20dp"
        android:layout_torightof="@id/three"
        android:text="第3个item"
        android:textcolor="#f0f0f0"
        android:textsize="20sp" />
    </relativelayout>
    <relativelayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content" >
      <imageview
        android:id="@+id/four"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_centervertical="true"
        android:layout_marginleft="20dp"
        android:layout_margintop="20dp"
        android:src="@mipmap/img_4" />
      <textview
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_centervertical="true"
        android:layout_marginleft="20dp"
        android:layout_torightof="@id/four"
        android:text="第一个item"
        android:textcolor="#f0f0f0"
        android:textsize="20sp" />
    </relativelayout>
    <relativelayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content" >
      <imageview
        android:id="@+id/five"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_centervertical="true"
        android:layout_marginleft="20dp"
        android:layout_margintop="20dp"
        android:src="@mipmap/img_5" />
      <textview
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_centervertical="true"
        android:layout_marginleft="20dp"
        android:layout_torightof="@id/five"
        android:text="第5个item"
        android:textcolor="#f0f0f0"
        android:textsize="20sp" />
    </relativelayout>
  </linearlayout>
</relativelayout> 

上一篇:

下一篇: