什么叫一站式
那还用问,就是一学就会呗。啦啦啦啦啦啦啦啦啦啦啦啦啦!
主要是我看别人的介绍的东西看得头大,一大堆重要细节都没有,漏了一点细节的话很多效果都没有。总得来说一站式就是吹牛皮。
文章比较长耐心看完就会用ToolBar+DrawerLayout使用
Android 自定义侧滑菜单效果(ViewDragHelper)
一、撸代码前要了解的东西
Google在2015的IO大会,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的Android Design Support Library,在这个support库里面,Google给我们提供了更加规范的MD设计风格的控件。最重要的是,Android Design Support Library的兼容性更广,直接可以向下兼容到Android 2.2。(敲黑板,这是重点拿笔记下来)
上面提到了Design Support Library
,要使用这个库当然是要引入到项目中咯,在Gradle中引入:
compile 'com.android.support:design:24.1.0'
CoordinatorLayout
等一些控件就是Material Design设计风格的控件,具体有哪些控件可以搜一下。望文生义这个控件就是协调控件:
- 扩展或者缩小Toolbar或者头部,让主内容区域有更多的空间。
- 控制哪个view应该扩展还是收缩,以及其显示大小比例,包括视差滚动效果动画。
看一下效果图呗(颜色不协调是为了更好的区分不同区域):
控制哪个view应该扩展还是收缩,以及其显示大小比例,包括视差滚动效果动画。
扩展或者缩小Toolbar或者头部,让主内容区域有更多的空间。
这三种效果主要都是根据xml来决定,当然还可以通过自定义Behavior来完成这个或者完成更复杂的效果,这些都不管,现在只用xml来完成。
如果效果还尽人意请往下看看呗。
二、CoordinatorLayout与CollapsingToolbar控制View的伸展与收缩
大致的效果在上图1所示。一下分解各个实现的步骤。
- 首先咱们要使用ToolBar一般都是要先隐藏原来的ActionBar,隐藏ActionBar有几种方法,这里我们就只在Manifest.xml里面进行配置。创建一个
activity
命名CoorCollapsingToolbarAct
然后在xml中进行注册并设置Theme
:
coordinatorTheme
是在res\values\styles.xml
中的自定义样式,父样式parent就是去掉ActionBar的样式如下:
- 要实现这些效果需结合
AppBarLayout
来共同完成:
-
AppBarLayout
必须作为CoordinatorLayout
的直接子View
,否则它的大部分功能将不会生效,如layout_scrollFlags
等。 -
AppBarLayout
它可以让你定制当某个可滚动View
的滚动手势发生变化时,其内部的子View
实现何种动作。 - 内部的子
View
通过在布局中加app:layout_scrollFlags
设置执行的动作,具体往下看。
- 知道什么是CollapsingToolBarLayout
- CollapsingToolbarLayout你可以像魔术一样让
Toolbar
折叠起来- 用 CollapsingToolbarLayout 包裹 Toolbar,但仍然在 AppBarLayout 中
- 从 Toolbar 不设置
layout_scrollFlags
- 为 CollapsingToolbarLayout 声明
layout_scrollFlags
,并且将layout_scrollFlags
设置成scroll|exitUntilCollapsed|snap
- 改变 AppBarLayout 扩张状态时的布局高度大小。在这个例子中,我用 250dp
app:layout_scrollFlags属性值
scroll: 所有想滚动出屏幕的view都需要设置这个flag, 没有设置这个flag的view将被固定在屏幕顶部。
snap: 在滚动结束后,如果view只是部分可见,它将滑动到最近的边界。
exitUntilCollapsed: 滚动退出屏幕,最后折叠在顶端。
还有enterAlways,enterAlwaysCollapsed等属性可以逐一试试看。
- xml编写
使用CoordinatorLayout往往是将他直接作为根布局来操作。创建activity_coor_collapsing.xml.
分析+解密[吹牛皮](敲黑板,文件中的注释是重点记下来要考)
- CollapsingToolbarLayout中的
statusBarScrim
:折叠时状态栏的颜色。前面在Activity的Theme
中将状态栏设置为透明色,所以当折叠ToolBar时会显示我们在这里设置的色值。如果在Theme
中不设置为透明这里将不起作用。 - 根布局CoordinatorLayout与AppBarLayout都要设置
android:fitsSystemWindows="true"
,如对此属性不懂可参考fitsystemwindows简单使用 - layout_behavior=”@string/appbar_scrolling_view_behavior”标志位(该Behavior系统以及帮我们实现),那么当带有这个标志位的控件滑动的时候会触发带有scroll_flags标志位的另一个控件进行滑动,此时imageview的layout_collapseMode是parallax,所以它会以有视差的方式来相对滑动,而toolbar设置了pin的标记位,所以在收缩后会固定在屏幕顶部。可在VIewPager中放置Recyclerview,ScrollView等滑动的布局(ListView与GridView不行)可进行联动.
比较奇葩的发现
暂时发现,如果你想实现title(图一的LOGO)的的效果,需设置CollapsingToolbarLayout的title值,然而5.x与4.x的系统不设置折叠样式
collapsedTitleTextAppearance
时,折叠时会将title默认隐藏,具体效果可以试试,不知道是不是机型问题,有待考察,6.x的系统不设置折叠时也会展示出来。
三、撸代码(图一效果)
因为用上了ViewPager
,所以顺带也用上了TabLayout
,不了解可以看看TabLayout高端用法,所以也结合了Fragment
实现。
- 大致创建一个简单的
Fragment
的基类BaseFragment:
/**
* Created by Leogh on 2017/8/28.
*/
public abstract class BaseFragment extends Fragment {
//这个title不用管 弄着玩的
public TextView tv_title;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = getLayoutView(inflater, container);
tv_title = (TextView) view.findViewById(R.id.tv_title);
init();
return view;
}
public abstract View getLayoutView(LayoutInflater inflater, ViewGroup container);
public abstract void init();
}
在创建三个Fragment,分别为Fragment1,Fragment2,Fragment3
简单粗暴嘛,这里只贴一个Fragment1的
代码,其它两个类似改一下就OK。
/**
* Created by Leogh on 2017/8/28.
*/
public class Fragment1 extends BaseFragment {
private View view;
private RecyclerView rv_page1;
private List mDatas = new ArrayList();
@Override
public View getLayoutView(LayoutInflater inflater, ViewGroup container) {
view = inflater.inflate(R.layout.fragment_page1, container, false);
return view;
}
@Override
public void init() {
initData();
tv_title.setText("one");
rv_page1 = (RecyclerView) view.findViewById(R.id.rv_page1);
rv_page1.setLayoutManager(new LinearLayoutManager(getActivity()));
rv_page1.setAdapter(new CoorAdapter(getActivity(), mDatas));
}
private void initData() {
for (int i = 0; i < 20; i++) {
mDatas.add("老腊肉" + i);
}
}
}
差点漏了Recyclerview的Adapter了CoorAdapter
:
/**
* Created by Leogh on 2017/8/29.
*/
public class CoorAdapter extends RecyclerView.Adapter {
private Context mContext;
private List mDatas;
public CoorAdapter(Context mContext, List mDatas) {
this.mContext = mContext;
this.mDatas = mDatas;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.main_list_item, parent, false);
return new MyViewHolder(v);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.textView.setText(mDatas.get(position));
}
@Override
public int getItemCount() {
return mDatas.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView textView;
public MyViewHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.textview);
}
}
}
Fragment1的布局文件fragment_page1.xml
:
最后主Activity上场CoorCollapsingToolbarAct
:
/**
* Created by Leogh on 2017/8/28.
* 图片渐变效果与CollapsingToolBarLayout(折叠ToolBar)
*
* 要实现此效果 需要使用 CoorinatorLayout (协调布局) AppBarLayout(导航布局) + 一个可以滑动的布局
* (注意 不支持 listView和GirdView)
*/
public class CoorCollapsingToolbarAct extends AppCompatActivity {
private Toolbar mToolBar;
private ViewPager mViewPager;
private TabLayout mTabLayout;
private CollapsingToolbarLayout main_collapsing;
private List mFragments;
private String[] mTitles = new String[]{"你", "我", "他"};
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_coordinator);
mToolBar = (Toolbar) findViewById(R.id.toolbar);
mToolBar.setLogo(android.R.drawable.ic_menu_add);
main_collapsing = (CollapsingToolbarLayout) findViewById(R.id.main_collapsing);
//手动设置title
// 注意:目前测试用的是5.1系统 发现不在xml中设置折叠字体样式,折叠时title也会直接隐藏,同时也试了4.4系统也是一样,6.0系统不会
//我也没有专门去测试,也不能直接得出结论说5.x与4.x的系统一定要设置 具体情况具体分析哈 多试试
main_collapsing.setTitle("LOGO");
setSupportActionBar(mToolBar);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mTabLayout = (TabLayout) findViewById(R.id.tabs);
setupViewPager();
}
private void setupViewPager() {
mFragments = new ArrayList();
mFragments.add(new Fragment1());
mFragments.add(new Fragment2());
mFragments.add(new Fragment3());
FragmentPagerAdapter adapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return mFragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
return mTitles[position];
}
};
mViewPager.setAdapter(adapter);
//ViewPager与TabLayout联动
mTabLayout.setupWithViewPager(mViewPager);
}
/**
* 如果有Menu,创建完后,系统会自动添加到ToolBar上
* 此方法用于初始化菜单,其中menu参数就是即将要显示的Menu实例。 返回true则显示该menu,false 则不显示;
* (只会在第一次初始化菜单时调用)
*
* @param menu
* @return
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
}
到此就可以看到图一的效果了,有很多属性可能没有分析,但是多试试才知道有什么效果。
四、撸代码(图2效果)
这里就只上xml文件了,代码都差不多 只是改了一下xml文件,将CollapsingToolBarLayout
去掉直接换成了ToolBar
来实现效果:
这样,滑动列表的时候就可以直接展示与折叠ToolBar了,不需要拉扯到列表顶部才能对ToolBar进行联动,如果非要以图一的形式来实现就需要自定义Behavior了(暂时没有发现其他方法)。
五、撸代码(图3效果)
注意:图三效果就是那个图标(FloatingActionButton)有渐变最后消失的一个过程的效果,图一中我们也对FloatingActionButton
做了同样的处理,可是并没有达到预期的效果:
- 暂时得出来的结论就是, 原因是图一中使用了TabLayout,去掉TabLayout就有渐变效果, 感觉是不能在AppBarLayout添加TabLayout来一起使用。所以这里只要把TabLayout去掉就可以了。
xml如下:
这个Activity的话就直接加载布局就行:
/**
* Created by Leogh on 2017/8/29.
* FloatingActionButton渐变效果
*/
public class CoorFloatingActionButtonAct extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.testfloatbutton);
}
}
可能有些细节漏了,但注释写的很详细,多留意注释。
最后提供一下官方Demo:点我点我点我