网上开源项目地址:https://github.com/ikimuhendis/LDrawer

效果图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQW5kZHJvaWRfTGFuWWFu/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

build.gradle

compile 'com.ikimuhendis:ldrawer:0.1'

colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ldrawer_color">#FFFFFF</color>
<color name="actionbar_color">#bf360c</color>
<color name="drawer_arrow_second_color">#303f9f</color>
</resources>

styles.xml

<resources>

    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<item name="android:actionBarStyle">@style/ActionBar</item>
</style> <style name="ActionBar" parent="android:Widget.ActionBar">
<item name="android:background">@color/actionbar_color</item>
<item name="android:icon">@android:color/transparent</item>
<item name="android:titleTextStyle">@style/ActionBar.TitleText</item>
</style> <style name="ActionBar.TitleText" parent="android:TextAppearance.Holo.Widget.ActionBar.Title">
<item name="android:textColor">@android:color/white</item>
<item name="android:textSize">18sp</item>
</style> </resources>

项目依赖开发包v4 : android.support.v4.app.ActionBarDrawerToggle,自己定义 DrawerArrowDrawable。ActionBarDrawerToggle

import android.app.ActionBar;
import android.app.Activity;
import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView; import java.lang.reflect.Method; import ldrawer.lanyan.com.ldrawer.R; public class ActionBarDrawerToggle extends android.support.v4.app.ActionBarDrawerToggle { private static final String TAG = ActionBarDrawerToggle.class.getName(); protected Activity mActivity;
protected DrawerLayout mDrawerLayout; protected int mOpenDrawerContentDescRes;
protected int mCloseDrawerContentDescRes;
protected DrawerArrowDrawable mDrawerImage;
protected boolean animateEnabled; public ActionBarDrawerToggle(Activity activity, DrawerLayout drawerLayout, int drawerImageRes, int openDrawerContentDescRes, int closeDrawerContentDescRes) {
super(activity, drawerLayout, drawerImageRes, openDrawerContentDescRes, closeDrawerContentDescRes);
} public ActionBarDrawerToggle(Activity activity, DrawerLayout drawerLayout, DrawerArrowDrawable drawerImage, int openDrawerContentDescRes, int closeDrawerContentDescRes) {
super(activity, drawerLayout, R.mipmap.ic_drawer, openDrawerContentDescRes, closeDrawerContentDescRes);
mActivity = activity;
mDrawerLayout = drawerLayout;
mOpenDrawerContentDescRes = openDrawerContentDescRes;
mCloseDrawerContentDescRes = closeDrawerContentDescRes;
mDrawerImage = drawerImage;
animateEnabled = true;
} public void syncState() {
if (mDrawerImage == null) {
super.syncState();
return;
}
if (animateEnabled) {
if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
mDrawerImage.setProgress(1.f);
} else {
mDrawerImage.setProgress(0.f);
}
}
setActionBarUpIndicator();
setActionBarDescription();
} public void setDrawerIndicatorEnabled(boolean enable) {
if (mDrawerImage == null) {
super.setDrawerIndicatorEnabled(enable);
return;
}
setActionBarUpIndicator();
setActionBarDescription();
} public boolean isDrawerIndicatorEnabled() {
if (mDrawerImage == null) {
return super.isDrawerIndicatorEnabled();
}
return true;
} public void onConfigurationChanged(Configuration newConfig) {
if (mDrawerImage == null) {
super.onConfigurationChanged(newConfig);
return;
}
syncState();
} public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
} @Override
public void onDrawerSlide(View drawerView, float slideOffset) {
if (mDrawerImage == null) {
super.onDrawerSlide(drawerView, slideOffset);
return;
}
if (animateEnabled) {
mDrawerImage.setVerticalMirror(!mDrawerLayout.isDrawerOpen(GravityCompat.START));
mDrawerImage.setProgress(slideOffset);
}
} @Override
public void onDrawerOpened(View drawerView) {
if (mDrawerImage == null) {
super.onDrawerOpened(drawerView);
return;
}
if (animateEnabled) {
mDrawerImage.setProgress(1.f);
}
setActionBarDescription();
} @Override
public void onDrawerClosed(View drawerView) {
if (mDrawerImage == null) {
super.onDrawerClosed(drawerView);
return;
}
if (animateEnabled) {
mDrawerImage.setProgress(0.f);
}
setActionBarDescription();
} protected void setActionBarUpIndicator() {
if (mActivity != null) {
try {
Method setHomeAsUpIndicator = ActionBar.class.getDeclaredMethod("setHomeAsUpIndicator",
Drawable.class);
setHomeAsUpIndicator.invoke(mActivity.getActionBar(), mDrawerImage);
return;
} catch (Exception e) {
Log.e(TAG, "setActionBarUpIndicator error", e);
} final View home = mActivity.findViewById(android.R.id.home);
if (home == null) {
return;
} final ViewGroup parent = (ViewGroup) home.getParent();
final int childCount = parent.getChildCount();
if (childCount != 2) {
return;
} final View first = parent.getChildAt(0);
final View second = parent.getChildAt(1);
final View up = first.getId() == android.R.id.home ? second : first; if (up instanceof ImageView) {
ImageView upV = (ImageView) up;
upV.setImageDrawable(mDrawerImage);
}
}
} protected void setActionBarDescription() {
if (mActivity != null && mActivity.getActionBar() != null) {
try {
Method setHomeActionContentDescription = ActionBar.class.getDeclaredMethod(
"setHomeActionContentDescription", Integer.TYPE);
setHomeActionContentDescription.invoke(mActivity.getActionBar(),
mDrawerLayout.isDrawerOpen(GravityCompat.START) ? mOpenDrawerContentDescRes : mCloseDrawerContentDescRes);
if (Build.VERSION.SDK_INT <= 19) {
mActivity.getActionBar().setSubtitle(mActivity.getActionBar().getSubtitle());
}
} catch (Exception e) {
Log.e(TAG, "setActionBarUpIndicator", e);
}
}
} public void setAnimateEnabled(boolean enabled) {
this.animateEnabled = enabled;
} public boolean isAnimateEnabled() {
return this.animateEnabled;
} }
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable; import ldrawer.lanyan.com.ldrawer.R; public abstract class DrawerArrowDrawable extends Drawable {
private static final float ARROW_HEAD_ANGLE = (float) Math.toRadians(45.0D);
protected float mBarGap;
protected float mBarSize;
protected float mBarThickness;
protected float mMiddleArrowSize;
protected final Paint mPaint = new Paint();
protected final Path mPath = new Path();
protected float mProgress;
protected int mSize;
protected float mVerticalMirror = 1f;
protected float mTopBottomArrowSize;
protected Context context; public DrawerArrowDrawable(Context context) {
this.context = context;
this.mPaint.setAntiAlias(true);
this.mPaint.setColor(context.getResources().getColor(R.color.ldrawer_color));
this.mSize = context.getResources().getDimensionPixelSize(R.dimen.ldrawer_drawableSize);
this.mBarSize = context.getResources().getDimensionPixelSize(R.dimen.ldrawer_barSize);
this.mTopBottomArrowSize = context.getResources().getDimensionPixelSize(R.dimen.ldrawer_topBottomBarArrowSize);
this.mBarThickness = context.getResources().getDimensionPixelSize(R.dimen.ldrawer_thickness);
this.mBarGap = context.getResources().getDimensionPixelSize(R.dimen.ldrawer_gapBetweenBars);
this.mMiddleArrowSize = context.getResources().getDimensionPixelSize(R.dimen.ldrawer_middleBarArrowSize);
this.mPaint.setStyle(Paint.Style.STROKE);
this.mPaint.setStrokeJoin(Paint.Join.ROUND);
this.mPaint.setStrokeCap(Paint.Cap.SQUARE);
this.mPaint.setStrokeWidth(this.mBarThickness);
} protected float lerp(float paramFloat1, float paramFloat2, float paramFloat3) {
return paramFloat1 + paramFloat3 * (paramFloat2 - paramFloat1);
} public void draw(Canvas canvas) {
Rect localRect = getBounds();
float f1 = lerp(this.mBarSize, this.mTopBottomArrowSize, this.mProgress);
float f2 = lerp(this.mBarSize, this.mMiddleArrowSize, this.mProgress);
float f3 = lerp(0.0F, this.mBarThickness / 2.0F, this.mProgress);
float f4 = lerp(0.0F, ARROW_HEAD_ANGLE, this.mProgress);
float f5 = 0.0F;
float f6 = 180.0F;
float f7 = lerp(f5, f6, this.mProgress);
float f8 = lerp(this.mBarGap + this.mBarThickness, 0.0F, this.mProgress);
this.mPath.rewind();
float f9 = -f2 / 2.0F;
this.mPath.moveTo(f9 + f3, 0.0F);
this.mPath.rLineTo(f2 - f3, 0.0F);
float f10 = (float) Math.round(f1 * Math.cos(f4));
float f11 = (float) Math.round(f1 * Math.sin(f4));
this.mPath.moveTo(f9, f8);
this.mPath.rLineTo(f10, f11);
this.mPath.moveTo(f9, -f8);
this.mPath.rLineTo(f10, -f11);
this.mPath.moveTo(0.0F, 0.0F);
this.mPath.close();
canvas.save();
if (!isLayoutRtl())
canvas.rotate(180.0F, localRect.centerX(), localRect.centerY());
canvas.rotate(f7 * mVerticalMirror, localRect.centerX(), localRect.centerY());
canvas.translate(localRect.centerX(), localRect.centerY());
canvas.drawPath(this.mPath, this.mPaint);
canvas.restore();
} public int getIntrinsicHeight() {
return this.mSize;
} public int getIntrinsicWidth() {
return this.mSize;
} public void setAlpha(int alpha) {
this.mPaint.setAlpha(alpha);
} @Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
} public abstract boolean isLayoutRtl(); public void setColorFilter(ColorFilter colorFilter) {
this.mPaint.setColorFilter(colorFilter);
} public void setVerticalMirror(boolean mVerticalMirror) {
this.mVerticalMirror = mVerticalMirror ? 1 : -1;
} public void setProgress(float paramFloat) {
this.mProgress = paramFloat;
invalidateSelf();
} public void setColor(int resourceId) {
this.mPaint.setColor(context.getResources().getColor(resourceId));
}
}

測试代码:

import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.widget.DrawerLayout;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView; import com.ikimuhendis.ldrawer.ActionBarDrawerToggle;
import com.ikimuhendis.ldrawer.DrawerArrowDrawable; public class SampleActivity extends Activity { private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private DrawerArrowDrawable drawerArrow;
private boolean drawerArrowColor; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample);
ActionBar ab = getActionBar();
ab.setDisplayHomeAsUpEnabled(true);
ab.setHomeButtonEnabled(true); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.navdrawer); drawerArrow = new DrawerArrowDrawable(this) {
@Override
public boolean isLayoutRtl() {
return false;
}
};
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
drawerArrow, R.string.drawer_open,
R.string.drawer_close) { public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
invalidateOptionsMenu();
} public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
invalidateOptionsMenu();
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerToggle.syncState(); String[] values = new String[]{
"Stop Animation (Back icon)",
"Stop Animation (Home icon)",
"Start Animation",
"Change Color",
"GitHub Page",
"Share",
"Rate"
};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1, values);
mDrawerList.setAdapter(adapter);
mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
switch (position) {
case 0:
mDrawerToggle.setAnimateEnabled(false);
drawerArrow.setProgress(1f);
break;
case 1:
mDrawerToggle.setAnimateEnabled(false);
drawerArrow.setProgress(0f);
break;
case 2:
mDrawerToggle.setAnimateEnabled(true);
mDrawerToggle.syncState();
break;
case 3:
if (drawerArrowColor) {
drawerArrowColor = false;
drawerArrow.setColor(R.color.ldrawer_color);
} else {
drawerArrowColor = true;
drawerArrow.setColor(R.color.drawer_arrow_second_color);
}
mDrawerToggle.syncState();
break;
case 4:
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/IkiMuhendis/LDrawer"));
startActivity(browserIntent);
break;
case 5:
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("text/plain");
share.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
share.putExtra(Intent.EXTRA_SUBJECT,
getString(R.string.app_name));
share.putExtra(Intent.EXTRA_TEXT, getString(R.string.app_description) + "\n" +
"GitHub Page : https://github.com/IkiMuhendis/LDrawer\n" +
"Sample App : https://play.google.com/store/apps/details? id=" +
getPackageName());
startActivity(Intent.createChooser(share,
getString(R.string.app_name)));
break;
case 6:
String appUrl = "https://play.google.com/store/apps/details?id=" + getPackageName();
Intent rateIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(appUrl));
startActivity(rateIntent);
break;
} }
});
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
if (mDrawerLayout.isDrawerOpen(mDrawerList)) {
mDrawerLayout.closeDrawer(mDrawerList);
} else {
mDrawerLayout.openDrawer(mDrawerList);
}
}
return super.onOptionsItemSelected(item);
} @Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState();
} @Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
}

布局文件:

<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"> <RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/app_description"/> </RelativeLayout> <!-- The navigation drawer -->
<ListView
android:id="@+id/navdrawer"
android:layout_width="@dimen/navdrawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="@android:color/white"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:drawSelectorOnTop="false">
</ListView> </android.support.v4.widget.DrawerLayout>

注意:假设是自己导入已有项目,复制图片时可能拷贝到的目录不是drawable(而是 R.mipmap.ic_drawer),那么
R.drawable.ic_drawer会报错找不到R

Android studio DrawerLayout的更多相关文章

  1. [Android] 升级了新的android studio之后 发生如下的报错,The following classes could not be instantiated:

    The following classes could not be instantiated:- android.support.v4.widget.DrawerLayout (Open Class ...

  2. Android下DrawerLayout的使用

    Android下DrawerLayout的使用 DrawerLayout见名知意,就是一个具有抽屉效果的布局,看看这个效果图,是不是感觉很炫酷 这么炫的效果其实不一定非要用类似一些SlidingMen ...

  3. 《Android Studio开发实战 从零基础到App上线》资源下载和内容勘误

    转载于:https://blog.csdn.net/aqi00/article/details/73065392 资源下载 下面是<Android Studio开发实战 从零基础到App上线&g ...

  4. Android Studio配置 AndroidAnnotations——Hi_博客 Android App 开发笔记

    以前用Eclicps 用习惯了现在 想学学 用Android Studio 两天的钻研终于 在我电脑上装了一个Android Studio 并完成了AndroidAnnotations 的配置. An ...

  5. Android Studio 多个编译环境配置 多渠道打包 APK输出配置

    看完这篇你学到什么: 熟悉gradle的构建配置 熟悉代码构建环境的目录结构,你知道的不仅仅是只有src/main 开发.生成环境等等环境可以任意切换打包 多渠道打包 APK输出文件配置 需求 一般我 ...

  6. Android Studio —— 重装 HAXM

    Android Studio -- 重装 HAXM 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 文中如有纰漏,欢迎大家留言指出. Android SDK 自带模拟器一直以慢.卡 ...

  7. android studio 使用 jni 编译 opencv 完整实例 之 图像边缘检测!从此在andrid中自由使用 图像匹配、识别、检测

    目录: 1,过程感慨: 2,运行环境: 3,准备工作: 4,编译 .so 5,遇到的关键问题及其解决方法 6,实现效果截图. (原创:转载声明出处:http://www.cnblogs.com/lin ...

  8. 使用 Android Studio 检测内存泄漏与解决内存泄漏问题

    本文在腾讯技术推文上 修改 发布. http://wetest.qq.com/lab/view/63.html?from=ads_test2_qqtips&sessionUserType=BF ...

  9. 【详细教程】论android studio中如何申请百度地图新版Key中SHA1值

    一.写在前面 现在越来越多的API接口要求都要求提供我们的项目SHA1值,开发版目前还要求不高,但是发布版是必定要求的.而目前定位在各大APP中也较为常见,当下主流的百度地图和高德地图都在申请的时候会 ...

随机推荐

  1. MySQL 5.7 安装完成后,首次登陆的几个问题

    Server:CentOS 7.0 MySQL : 5.7.20 MySQL Community Server (GPL) 1.首次登陆后修改密码: 根据安装时的选择不同,有mysqld_safe用m ...

  2. 使用matplotlib绘图(一)之折线图

    # 使用matplotlib绘制折线图 import matplotlib.pyplot as plt import numpy as np # 在一个图形中创建两条线 fig = plt.figur ...

  3. hibernate 基于主键的单向一对一关联映射

    1.设计表结构 表结构对于基于外键的关联关系来说就少了外键的关联列,并且两张表共用同一个ID,表示一对一. 2.创建Person对象 3.创建IdCard对象 4.写hbm.xml文件 5.生成数据库 ...

  4. Hibernate 双向一对多的关联映射

    双向的一对多的关联关系是单项的一对多和单项的多对一的情况下产生的. 1.设计表结构 虽然关联关系变为双向的一对多,但是我们表结构不会发生改变,只是指向变了. 2.创建student对象 3.创建Gra ...

  5. 我的OI生涯 第一章

    第一章   一入电竞深似海 我叫WZY,是TSYZ的一名学生. 2016年7月10日,我进了一个叫做oi的坑. 那时的我不知道什么叫竞赛,不知道什么叫编程,不知道什么是c++. 就记得前一天我特意去图 ...

  6. RE:从零开始的AGC被虐(到)生活(不能自理)

    RE:从零开始的AGC被虐(到)生活(不能自理) 「一直注视着你,似近似远,总是触碰不到.」 --来自风平浪静的明天 AtCoder Grand Contest 001 B: Mysterious L ...

  7. 【20181027T2】易水决【贪心+堆】

    原题:loj6035 [错解] 全肝T1了没怎么想 [正解] 一眼贪心 先考虑\(b_i=0\)怎么做 可以模拟一个正常人的思维 开一个堆,记录每个任务需要的时间(包括等待),每次从中取出一个任务,表 ...

  8. 1.6(SQL学习笔记)存储过程

    一.什么事存储过程 可以将存储过程看做是一组完成某个特定功能的SQL语句的集合. 例如有一个转账功能(A向B转账50),先将账户A中金额扣除50,然后将账户B中金额添加50. 那么我们可以定义一个名为 ...

  9. Java解释执行和编译执行

    以前有句话说:“Java是解释执行的 ” .现在看来确实不是很准确,至于原因,在此简略解释: 首先,我们先解释一下在Java中解释执行和编译执行的区别. 解释执行:将编译好的字节码一行一行地翻译为机器 ...

  10. bzoj 1004 Cards 组合计数

    这道题考察的是组合计数(用Burnside,当然也可以认为是Polya的变形,毕竟Polya是Burnside推导出来的). 这一类问题的本质是计算置换群(A,P)中不动点个数!(所谓不动点,是一个二 ...