安卓Design包之超强控件CoordinatorLayout与SnackBar的简单使用
在前面的Design中,学习使用了TabLayout,NavigationView与DrawerLayout实现的神奇效果,今天就带来本次Design包中我认为最有意义的控件CoordinatorLayout。
当然还有SnackBar,不过他在实际运用中一般都是和CoordinatorLayout搭配使用的。
先说下SnackBar,这个控件其实我觉得和Toast没什么差别,不过功能上的确有增强。这个控件可以通过setAction方法设置类似按钮一样的东西。而且这个东西可以设置多个。
重点还是我们的CoordinatorLayout控件,这是一个增强型的FrameLayout,功能非常强大,可以给它的子布局增加很多有意思的东西。
它通常和Behavior联合在一起使用。
项目已同步至github:https://github.com/nanchen2251/CoordinatorLayout(包括了下一节内容的源代码)
先上一波运行图:
可以在Behavior中通过监听Scoll来实现控件的显示和隐藏
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | package com.example.nanchen.designcoodinatordemo; import android.content.Context; import android.support.design.widget.CoordinatorLayout; import android.support.v4.view.ViewCompat; import android.util.AttributeSet; import android.view.View; /** * 自定义Behavior * Created by 南尘 on 16-7-14. */ public class MyBehavior extends CoordinatorLayout.Behavior { //写了这个构造方法才能在XML文件中直接指定 public MyBehavior(Context context, AttributeSet attrs) { super (context, attrs); } @Override public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) { return true ; //返回true代表我们关心这个滚动事件 } @Override public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int [] consumed) { super .onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed); if (dy < 0 ) { //向下滚动 ViewCompat.animate(child).scaleX( 1 ).alpha( 1 ).start(); } else { //向上滚动 ViewCompat.animate(child).scaleX( 0 ).alpha( 0 ).start(); } } } |
这样在下拉的时候就会消失。
值得注意的是,若是想在XML中显示指定Behavior的话,必须重写构造方法
1 2 3 | public MyBehavior(Context context, AttributeSet attrs) { super (context, attrs); } |
其他的一些代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | package com.example.nanchen.designcoodinatordemo; import android.os.Bundle; import android.support.design.widget.Snackbar; import android.support.design.widget.SwipeDismissBehavior; import android.support.v4.view.ViewCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.TextView; import java.util.ArrayList; import java.util.List; import java.util.Locale; public class MainActivity extends AppCompatActivity implements SwipeDismissBehavior.OnDismissListener { private TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv = (TextView) findViewById(R.id.main_tv); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.main_recycler); List<String> list = new ArrayList<>(); for ( int i = 0 ; i < 100 ; i++) { list.add(String.format(Locale.CHINA, "第%03d行" ,i)); } MyAdapter adapter = new MyAdapter(list, this ); recyclerView.setAdapter(adapter); // CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) tv.getLayoutParams(); // SwipeDismissBehavior<TextView> behavior = new SwipeDismissBehavior<>(); // behavior.setListener(this);//设置一个监听 // params.setBehavior(behavior);//设置一个行为 // MyBehavior behavior = new MyBehavior(); // params.setBehavior(behavior); } @Override public void onDismiss(View view) { view.setVisibility(View.GONE); Snackbar.make(view, "删除了一个控件!" ,Snackbar.LENGTH_SHORT) .setAction( "撤销" , new View.OnClickListener() { @Override public void onClick(View v) { tv.setVisibility(View.VISIBLE); ViewCompat.animate(tv).alpha( 1 ).start(); //把透明度设置为1 } }).show(); } @Override public void onDragStateChanged( int state) { } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | package com.example.nanchen.designcoodinatordemo; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.ViewGroup; import android.widget.TextView; import java.util.List; /** * Created by 南尘 on 16-7-14. */ public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private List<String> list; private Context context; public MyAdapter(List<String> list, Context context) { this .list = list; this .context = context; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { TextView textView = new TextView(context); return new RecyclerView.ViewHolder(textView) {}; } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { ((TextView) holder.itemView).setText(list.get(position)); } @Override public int getItemCount() { return list.size(); } } |
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.nanchen.designcoodinatordemo.MainActivity">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="LinearLayoutManager"
android:id="@+id/main_recycler"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:background="#f00"
android:clickable="true"
android:layout_gravity="center"
android:id="@+id/main_tv"
app:layout_behavior="com.example.nanchen.designcoodinatordemo.MyBehavior"
android:text="Hello World!"/>
</android.support.design.widget.CoordinatorLayout>
作 者:
南 尘
出 处: http://www.cnblogs.com/liushilin/
关于作者:专注于移动前端的项目开发。如有问题或建议,请多多赐教!欢迎加入Android交流群:118116509
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我
声援博主:如果您觉得文章对您有帮助,可以点击文章下部【推荐】或侧边【关注】。您的鼓励是作者坚持原创和持续写作的最大动力!
欢迎关注我的公众号,精讲面试、算法、Andrid、Java、Python,旨在打造全网最比心的公众号。

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述