1,前天在git上看到了一个不错的控件 ,最近两天项目也没有那么赶了,就抽时间来写写代码,锻炼一下手感,先看一下效果吧。

2 整体来看 ,主要是有两块来实现的,①主界面的RecyclerView ,②菜单栏的LeftDrawerLayout ,

先来将这个控件引到项目中  ,在build.gradle加入以下代码

compile 'com.mxn.soul:flowingdrawer-core:1.2.2'
compile 'com.nineoldandroids:library:2.4.0'

  

主界面的布局activity.xml

<?xml version="1.0" encoding="utf-8"?>
<com.mxn.soul.flowingdrawer_core.LeftDrawerLayout
android:id="@+id/lf_drawerlayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
>
<!-- android:clipChildren="false" 这个属性是不限制子控件在其范围内-->
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/> <android.support.design.widget.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="@+id/toolbar"
layout="@layout/toolbar"/>
</android.support.design.widget.AppBarLayout> </android.support.design.widget.CoordinatorLayout> <!--menu-->
<RelativeLayout
android:layout_width="280dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:clipChildren="false"
>
<com.mxn.soul.flowingdrawer_core.FlowingView
android:id="@+id/flowingView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!--FlowingView 是弹出的那多余的那一块--> <FrameLayout
android:id="@+id/frame_container_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_marginRight="25dp"
android:paddingRight="10dp"
/>
</RelativeLayout>
</com.mxn.soul.flowingdrawer_core.LeftDrawerLayout>

toolbar.xml 代码

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar android:id="@+id/toolbar"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:elevation="@dimen/default_elevation"
app:layout_scrollFlags="scroll|enterAlways"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
</android.support.v7.widget.Toolbar>

MainActivity.java

package wangjitao.com.flowingdrawerdemo;

import android.content.Context;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.View; import com.mxn.soul.flowingdrawer_core.FlowingView;
import com.mxn.soul.flowingdrawer_core.LeftDrawerLayout; public class MainActivity extends AppCompatActivity {
private Context mContext = MainActivity.this ;
private RecyclerView mRecyclerView ;
private LeftDrawerLayout mLeftDrawerLayout ;
private FlowingView mFlowingView ;
private MyFeedAdapter mMyFeedAdapter ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupToolbar(); initView();
} private void initView() {
mLeftDrawerLayout = (LeftDrawerLayout) findViewById(R.id.lf_drawerlayout); //用于设置左边的drawlayout
FragmentManager mFragmentManager = getSupportFragmentManager() ;
MyMenuFragment mMenuFragment = (MyMenuFragment) mFragmentManager.findFragmentById(R.id.frame_container_menu);
mFlowingView = (FlowingView) findViewById(R.id.flowingView);
if (mMenuFragment == null) {
mFragmentManager.beginTransaction().add(R.id.frame_container_menu, mMenuFragment = new MyMenuFragment()).commit();
}
mLeftDrawerLayout.setFluidView(mFlowingView);
mLeftDrawerLayout.setMenuFragment(mMenuFragment); mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this) {
@Override
protected int getExtraLayoutSpace(RecyclerView.State state) {
return 300;
}
});
mMyFeedAdapter = new MyFeedAdapter(mContext);
mRecyclerView.setAdapter(mMyFeedAdapter); } private void setupToolbar() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setNavigationIcon(R.mipmap.ic_menu_white); toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mLeftDrawerLayout.toggle();
}
}); } @Override
public void onBackPressed() {
if (mLeftDrawerLayout.isShownMenu()){
mLeftDrawerLayout.closeDrawer();
}else {
super.onBackPressed();
}
}
}

 再看看我们关键的自定义的FragmentLayout

package wangjitao.com.flowingdrawerdemo;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.NavigationView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast; import com.mxn.soul.flowingdrawer_core.MenuFragment;
import com.squareup.picasso.Picasso; public class MyMenuFragment extends MenuFragment { private ImageView ivMenuUserProfilePhoto; @Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
} @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_menu, container,
false);
NavigationView mNavigationView = (NavigationView) view.findViewById(R.id.vNavigation) ;
ivMenuUserProfilePhoto = (ImageView) mNavigationView.getHeaderView(0).findViewById(R.id
.ivMenuUserProfilePhoto);
setupHeader();
return setupReveal(view) ;
} private void setupHeader() {
int avatarSize = getResources().getDimensionPixelSize(R.dimen.global_menu_avatar_size);
String profilePhoto = getResources().getString(R.string.user_profile_photo);
Picasso.with(getActivity())
.load(profilePhoto)
.placeholder(R.drawable.img_circle_placeholder)
.resize(avatarSize, avatarSize)
.centerCrop()
.transform(new CircleTransformation())
.into(ivMenuUserProfilePhoto);
} public void onOpenMenu(){ }
public void onCloseMenu(){ }
}

 菜单栏中的布局文件fragment_menu.xml

    <RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"> <android.support.design.widget.NavigationView
android:id="@+id/vNavigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="@android:color/transparent"
app:headerLayout="@layout/menu_header"
app:itemIconTint="#8b8b8b"
app:itemTextColor="#666666"
app:menu="@menu/drawer_menu"/>
</RelativeLayout>

  menu_head.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:clickable="true">
<LinearLayout
android:id="@+id/vGlobalMenuHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"> <ImageView
android:id="@+id/ivMenuUserProfilePhoto"
android:layout_width="@dimen/global_menu_avatar_size"
android:layout_height="@dimen/global_menu_avatar_size"
android:layout_margin="12dp" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:text="阿呆哥哥"
android:textColor="#2d5d82"
android:textSize="16sp"
android:textStyle="bold" /> <ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_margin="16dp"
android:background="@android:color/transparent"
android:src="@mipmap/ic_global_menu_search" /> </LinearLayout> <View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="bottom"
android:background="#dddddd" />
</FrameLayout>

  看一下menu_head的截图

drawer_menu.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:id="@+id/menu_group_1">
<item
android:id="@+id/menu_feed"
android:icon="@mipmap/ic_global_menu_feed"
android:title="My Feed" />
<item
android:id="@+id/menu_direct"
android:icon="@mipmap/ic_global_menu_direct"
android:title="Instagram Direct" />
<item
android:id="@+id/menu_news"
android:icon="@mipmap/ic_global_menu_news"
android:title="News" />
<item
android:id="@+id/menu_popular"
android:icon="@mipmap/ic_global_menu_popular"
android:title="Popular" />
<item
android:id="@+id/menu_photos_nearby"
android:icon="@mipmap/ic_global_menu_nearby"
android:title="Photos Nearby" />
<item
android:id="@+id/menu_photo_you_liked"
android:icon="@mipmap/ic_global_menu_likes"
android:title="Photos You've Liked" />
</group> <group android:id="@+id/menu_group_2">
<item
android:id="@+id/menu_settings"
android:title="Settings" />
<item
android:id="@+id/menu_about"
android:title="About" />
</group>
</menu>

到这里基本上的模型就出来了,看效果 :

加上制作用户头像的圆形制作的CircleTransformation.class

package wangjitao.com.flowingdrawerdemo;

import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint; import com.squareup.picasso.Transformation; public class CircleTransformation implements Transformation { private static final int STROKE_WIDTH = 6; @Override
public Bitmap transform(Bitmap source) {
int size = Math.min(source.getWidth(), source.getHeight()); int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2; Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
if (squaredBitmap != source) {
source.recycle();
} Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig()); Canvas canvas = new Canvas(bitmap); Paint avatarPaint = new Paint();
BitmapShader shader = new BitmapShader(squaredBitmap, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
avatarPaint.setShader(shader); Paint outlinePaint = new Paint();
outlinePaint.setColor(Color.WHITE);
outlinePaint.setStyle(Paint.Style.STROKE);
outlinePaint.setStrokeWidth(STROKE_WIDTH);
outlinePaint.setAntiAlias(true); float r = size / 2f;
canvas.drawCircle(r, r, r, avatarPaint);
canvas.drawCircle(r, r, r - STROKE_WIDTH / 2, outlinePaint); squaredBitmap.recycle();
return bitmap;
} @Override
public String key() {
return "circleTransformation()";
}
}

  再加上RecyclerView的Adapter,基本上就成功了

package wangjitao.com.flowingdrawerdemo;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextSwitcher;
import android.widget.TextView; /**
* Created by wangjitao on 2016/4/14.
*/
public class MyFeedAdapter extends RecyclerView.Adapter<MyFeedAdapter.MyFeedViewHolder> {
private Context context;
private int likeCount = 123 ;
public MyFeedAdapter(Context context) {
this.context = context;
} @Override
public MyFeedViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_recyclerview, parent, false);
return new MyFeedViewHolder(view);
} @Override
public void onBindViewHolder(final MyFeedViewHolder holder, int position) {
if (position % 2 == 0) {
holder.ivFeedCenter.setImageResource(R.mipmap.img_feed_sakura);
holder.ivFeedBottom.setImageResource(R.mipmap.img_feed_bottom_1);
} else {
holder.ivFeedCenter.setImageResource(R.mipmap.img_feed_water);
holder.ivFeedBottom.setImageResource(R.mipmap.img_feed_bottom_2);
} holder.btnComments.setTag(position);
holder.btnMore.setTag(position);
holder.ivFeedCenter.setTag(holder);
holder.btnLike.setTag(holder); holder.iv_likes.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
holder.tv_likes_count.setText((++likeCount)+" likes");
}
});
} @Override
public int getItemCount() {
return 10;
} class MyFeedViewHolder extends RecyclerView.ViewHolder {
ImageView ivFeedCenter;
ImageView ivFeedBottom;
ImageButton btnComments;
ImageButton btnLike;
ImageButton btnMore;
TextSwitcher tsLikesCounter;
ImageView ivUserProfile;
FrameLayout vImageRoot;
ImageView iv_likes;
TextView tv_likes_count ; public MyFeedViewHolder(View view) {
super(view); ivFeedCenter = (ImageView) view.findViewById(R.id.ivFeedCenter);
ivFeedBottom = (ImageView) view.findViewById(R.id.ivFeedBottom);
btnComments = (ImageButton) view.findViewById(R.id.btnComments);
btnLike = (ImageButton) view.findViewById(R.id.btnLike);
btnMore = (ImageButton) view.findViewById(R.id.btnMore);
tsLikesCounter = (TextSwitcher) view.findViewById(R.id.tsLikesCounter);
ivUserProfile = (ImageView) view.findViewById(R.id.ivUserProfile);
vImageRoot = (FrameLayout) view.findViewById(R.id.vImageRoot);
iv_likes = (ImageView) view.findViewById(R.id.iv_likes);
tv_likes_count = (TextView) view.findViewById(R.id.tv_likes_count);
}
}
}

  项目下载地址:点击下载(嘿嘿嘿)

  

 

 

  

  

Android 优秀UI控件 ---- FlowingDrawer的更多相关文章

  1. [Android] Android 让UI控件固定于底部的几种方法

    Android 让UI控件固定于底部的几种方法1.采用linearlayout布局:android:layout_height="0dp" <!-- 这里不能设置fill_p ...

  2. Android之UI控件

    本文主要包括以下内容 Spinner的使用 Gallery的使用 Spinner的使用 Spinner的实现过程是 1. 在xml文件中定义Spinner的控件 2. 在activity中获取Spin ...

  3. Android 常用UI控件之TabHost(5)Tab栏在底部且在最上层也不盖tab页

    tab栏在底部 <TabHost android:id="@android:id/tabhost" android:layout_width="match_pare ...

  4. Android 常用UI控件之TabHost(4)实现当Tab栏有多个tab时,可以左右滑动

    <!-- <HorizontalScrollView android:id="@+id/horizontalScrollView1" android:layout_wi ...

  5. Android 常用UI控件之TabHost(2)简单示例

    1,布局 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tool ...

  6. Android 常用UI控件之TabHost(1)TabHost的两种布局方式

    TabHost是Android中的tab组件. TabHost布局文件的基本结构 TabHost下有个layout,这个layout中有TabWidget与FrameLayout.TabWidget是 ...

  7. Android 常用UI控件之TabHost(3)在4.0不显示图标的解决方案

    1,自定义 TabWidget 上每个tab的view 2,用多个图片

  8. Android 常用UI控件之Tab控件的实现方案

    实现Tab的方式有多种 1,ActionBar有两种模式可以实现,但是已经过期 tab模式tab在顶部,分裂模式tab在底部(同时所有action item都在底部). 2,PagerTitleStr ...

  9. ANDROID L——Material Design详解(UI控件)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! Android L: Google已经确认Android L就是Android Lolli ...

随机推荐

  1. pod setup》error: RPC failed; result=18, HTTP code = 200

    Try reducing the postBuffer size in the remote repository config. Follow the steps below Go to remot ...

  2. const与#define宏常量 , inline与#define

    1.预处理 预处理器是在真正的编译开始之前由编译器调用的独立程序.预处理器可以删除注释.包含其他文件以及执行宏替代. 预处理命令(宏定义#define..#undef. 文件包含#include. 条 ...

  3. imx6 uboot lcd

    本文记录imx6 uboot中关于lcd初始化的过程. uboot中相关的文件: cpu/arm_cortexa8/start.S lib_arm/board.c board/freescale/mx ...

  4. js运算之比较大小

    1.大于>和小于< var box = 3 > 2;//关系运算符大多返回的是一boolean值. alert(box); //true 1.2不同类型的数据比较 var box = ...

  5. PHP回调函数的几种用法

    PHP回调函数的实现方法 目录 前言      全局函数的回调      类静态函数的回调      对象的方法的回调      PHP事件模型(观察者模式)的实现思路    前言 最近在开发一个PH ...

  6. nc 反弹链接

    nc -l -v -p 80在本机监听80端口,此时80端口是打开的,我们可以在浏览器输入127.0.0.1进行浏览,此时就会出现连接,我们再在监听窗口输入字符,就会在浏览器上显示了.知道上面的作用后 ...

  7. Netty中BIO,NIO

    同步阻塞io(BIO).伪异步io(PIO).非阻塞io(NIO).异步io(AIO)的概念及区别? 同步阻塞io(BIO):服务器端与客户端通过三次握手后建立连接,连接成功,双方通过I/O进行同步阻 ...

  8. CAM350测量

    CAM350 测量方法 1. 单位设置:在菜单:Settings 下选中 Unit: 英制 公制 精确度 CAM350 软件默认的是英制,不习惯用英制的人,就改为公制的呀 软件默认的是英制 就改为公制 ...

  9. 关于开源授权协议 GPL 和 LGPL

    GPL 是 GNU General Public License (GNU 通用公共许可证)的缩写形式:LGPL 是 GNU Lesser General Public License (GNU 宽通 ...

  10. [Call Vibrator] How to Enable Outgoing Call Vibration without ROOT

    Call Vibrator requires the radio log of phone to detect when outgoing call is answered. But since An ...