• 2、Android-UI(RecyclerView)


    2.6、滚动控件-RecylerView

    ListView虽然使用的效果很好但是也是有缺点的

    不使用一些技巧来提升它的运行效率,性能就非常差

    扩展性也不是很好

    只能实现数据的纵向滚动效果

    实现横向滚动是做不到的

    Android提供一个更强大的滚动控件---RecylerView

    是一个增强版的ListView

    不仅可以轻松实现和ListView同样效果

    还优化了ListView中 存在的不足之处

    目前官方更推荐使用RecyclerView

    未来会有更多的程序主键从ListView转向RecyclerView

    1、基本用法

    首先再app/build.gradle文件中引入:

       compile 'com.android.support:recyclerview-v7:23.4.0'

    再first_activity中:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        </android.support.v7.widget.RecyclerView>
           
    </LinearLayout>

    新建一个适配类

    继承RecyclerView.Adapter,并且将泛型指定为内部类ViewHolder

    public class FruitAdaperRecyler extends RecyclerView.Adapter<FruitAdaperRecyler.ViewHolder> {
        private List<Fruit> fruitList;
    
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,null,false);
            ViewHolder viewHolder = new ViewHolder(view);
            return viewHolder;
        }
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            Fruit fruit = fruitList.get(position);
            holder.textView.setText(fruit.getName());
           holder.imageView.setImageResource(fruit.getId());
    
        }
        @Override
        public int getItemCount() {
            return fruitList.size();
        }
    
         //自定义的内部类
          class ViewHolder extends RecyclerView.ViewHolder{
            //布局文件中的两个控件
            ImageView imageView;
            TextView textView;
            public ViewHolder(View itemView) {
                super(itemView);
                imageView  = (ImageView) itemView.findViewById(R.id.image_view);
                textView = (TextView) itemView.findViewById(R.id.text_view);
            }
        }
    
        //构造器
        public FruitAdaperRecyler(List<Fruit> fruits){
            this.fruitList = fruits;
        }
    }

    首先定义一个内部类ViewHolder

    需要继承RecyclerHolder

    然后再构造参数中要传入一个view参数

    这个参数通常就是RecyclerView子项的最外层布局

    那么就可以通过findViewById()方法获取到布局中的ImageView和TextView的实例

    FruitAdaperRecyler类中有一个构造函数就是将要展示的数据传进来

    并且复制给一个全局变量,后续的操作都是在全局变量的基础上进行的

    FruitAdaperRecyler继承RecyclerView.Adapter就需要实现其中的三个方法

    1、omCreateViewHolder()方法就是用于创建viewholder的实例,再方法中将fruit_item布局加载进来

      然后创建一个viewHolder实例,并把加载出来的布局传入传入到构造函数中

      最后将viewHolder的实例返回

    2、onBinbViewHolder()方法用于对Recycler子项的数据进行赋值,会在每一个子项被滚动到屏幕内时执行

      这里通过position参数可以获得到当前的Fruit的实例,然后进行设置id和name

    3、getItemCount()就是返回REcyclerView一共有多少个子项,直接返回数据源的长度即可

    mainAcctivity中的代码:

    public class MainActivity extends AppCompatActivity {
        private List<Fruit> fruitList = new ArrayList<>();
    
        private void initFruit(){
                Fruit apple = new Fruit("Apple1",R.drawable.qq);
                fruitList.add(apple);
                Fruit apple1 = new Fruit("Apple2",R.drawable.qq);
                fruitList.add(apple1);
                Fruit apple2 = new Fruit("Apple3",R.drawable.qq);
                fruitList.add(apple2);
                Fruit apple3 = new Fruit("Apple4",R.drawable.qq);
                fruitList.add(apple3);
                Fruit apple4 = new Fruit("Apple5",R.drawable.qq);
                fruitList.add(apple4);
                Fruit apple5 = new Fruit("Apple6",R.drawable.qq);
                fruitList.add(apple5);
                Fruit apple6 = new Fruit("Apple7",R.drawable.qq);
                fruitList.add(apple6);
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.firstlayout);
            ActionBar actionBar = getSupportActionBar();
            if (actionBar != null){
                actionBar.hide();
            }
            //初始化
            initFruit();
    
            RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyler_view);
    
            LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
            recyclerView.setLayoutManager(linearLayoutManager);
            FruitAdaperRecyler fruitAdaperRecyler = new FruitAdaperRecyler(fruitList);
    
            recyclerView.setAdapter(fruitAdaperRecyler);
        }
    }

    使用initFruit进行初始化数据

    再onCreate()方法中首先获取RecyclerView的实例

    然后创建一个LinearLayoutManager对象,在这里是线性布局的意思

    再进行创建FruitAdapterRecyler的实例

    并且将水果的数据传入

    醉胡调用RecyclerView的setAdapter()方法来完成适配器的设置

    此时RecyrView和数据之间的关联建立完成

    实现了和ListView几乎一样的效果

    再实现的过程中逻辑清晰

    2、实现横向滚动和瀑布流布局

    文件中的布局元素都是水平排列的

    适用于纵向滚动的场景

     实现横向滚动则需要改成垂直排列

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="100dp"
        android:layout_height="match_parent">
    
        <ImageView
            android:id="@+id/image_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
    
            />
        <TextView
            android:id="@+id/text_view"
            android:layout_marginTop="10dp"
            android:layout_gravity="center_horizontal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    
    </LinearLayout>

    将LinerLayout改成垂直方向的排列

    此时设置的宽度时100dp

    将宽度指定为固定的值可以有效的包裹文字,防止其过长或者过短的美观问题

    进行修改代码:

     @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.firstlayout);
            ActionBar actionBar = getSupportActionBar();
            if (actionBar != null){
                actionBar.hide();
            }
            //初始化
            initFruit();
    
            RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyler_view);
    
            LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
            linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
    
            recyclerView.setLayoutManager(linearLayoutManager);
            FruitAdaperRecyler fruitAdaperRecyler = new FruitAdaperRecyler(fruitList);
    
            recyclerView.setAdapter(fruitAdaperRecyler);
        }

     之加入了一行代码

    调用LinearLayoutManager的setOrientation()方法来设置不久排列的排列方向

    此时的设置表示横向排列

    默认是纵向排列

     处LInearLayoutManager之外

    还提供了GridLayoutManagerStaggeredGridLayoutManager这两种内置的布局排列方式

    前者可以实现网格布局

    后者可以实现瀑布流布局

     

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp">
    
        <ImageView
            android:id="@+id/image_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
    
            />
        <TextView
            android:id="@+id/text_view"
            android:layout_marginTop="10dp"
            android:layout_gravity="center_horizontal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    
    </LinearLayout>

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.firstlayout);
            ActionBar actionBar = getSupportActionBar();
            if (actionBar != null){
                actionBar.hide();
            }
            //初始化
            initFruit();
    
            RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyler_view);
    
            StaggeredGridLayoutManager staggeredGridLayoutManager =  new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
            recyclerView.setLayoutManager(staggeredGridLayoutManager);
            FruitAdaperRecyler fruitAdaperRecyler = new FruitAdaperRecyler(fruitList);
            recyclerView.setAdapter(fruitAdaperRecyler);
        }
    StaggeredGridLayoutManager staggeredGridLayoutManager =  new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
    

    第一个参数用于指定列数

    第二个参数用于指定布局的排列方向

     结果展示:

    3、点击事件:

    所有的点击事件都有具体的View去注册

    代码如下: 

    public class FruitAdaperRecyler extends RecyclerView.Adapter<FruitAdaperRecyler.ViewHolder> {
        private List<Fruit> fruitList;
    
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,null,false);
            final ViewHolder viewHolder = new ViewHolder(view);
    
            //点击事件的监听
            viewHolder.fruitView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int position = viewHolder.getAdapterPosition();
                    Fruit fruit = fruitList.get(position);
                    Toast.makeText(v.getContext(),"clicked:"+fruit.getName(),Toast.LENGTH_LONG).show();
                }
            });
            viewHolder.imageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int position = viewHolder.getAdapterPosition();
                    Fruit fruit = fruitList.get(position);
                    Toast.makeText(v.getContext(),"click image :" + fruit.getName(),Toast.LENGTH_LONG).show();
                }
            });
    
            return viewHolder;
        }
    
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            Fruit fruit = fruitList.get(position);
            holder.textView.setText(fruit.getName());
           holder.imageView.setImageResource(fruit.getId());
    
        }
    
        @Override
        public int getItemCount() {
            return fruitList.size();
        }
    
    
         //自定义的内部类
          class ViewHolder extends RecyclerView.ViewHolder{
            //布局文件中的两个控件
            ImageView imageView;
            TextView textView;
             View fruitView;
    
            public ViewHolder(View itemView) {
                super(itemView);
                fruitView=itemView;
                imageView  = (ImageView) itemView.findViewById(R.id.image_view);
                textView = (TextView) itemView.findViewById(R.id.text_view);
            }
        }
    
        //构造器
        public FruitAdaperRecyler(List<Fruit> fruits){
            this.fruitList = fruits;
        }
    }

    首先是在ViewHolder中添加了fruitView变量来保存子项最外层的布局实例

    然后再onCreateViewHolder()方法中注册点击事件

    首先是获取用户点击的position

    然后通过position获取用户拿到享用的Fruit实例

    最后将内容进行显示

    点击文字和图片都可以正常的进行打印显示的信息

  • 相关阅读:
    图像滤波
    直方图histeq
    直方图
    基于灰度变换的图像增强
    图像增强
    图像旋转和缩放
    图像点运算
    像素的连接与联通
    程序员进阶之算法练习(一)
    RxSwift 系列(二)
  • 原文地址:https://www.cnblogs.com/Mrchengs/p/10674544.html
Copyright © 2020-2023  润新知