安卓常用控件RecyclerView+HorizontalScrollView实现item侧滑效果

来源:互联网 发布:下载手机开关机软件 编辑:程序博客网 时间:2024/06/05 17:11

   简单来介绍下RecyclerView,首先这个控件要做的事类似ListView,实际上它就是为了弥补ListView的不足而出现,那么我们来看下它的简单应用吧!

  先上效果图

 

   RecyclerView是新增的控件,所以在使用这个控件时必须先在app/build.gradle文件中添加依赖闭包(dependencies)

dependencies {    compile fileTree(dir: 'libs', include: ['*.jar'])    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {        exclude group: 'com.android.support', module: 'support-annotations'    })    compile 'com.android.support:appcompat-v7:26.0.0-alpha1'    compile 'com.android.support:design:26.0.0-alpha1'    testCompile 'junit:junit:4.12'    compile'com.android.support:recyclerview-v7:24.2.1'   //RecyclerView 的依赖闭包    compile 'com.google.android.gms:play-services-appindexing:8.4.0'}

添加完后点击Sync Now同步,到这里所有的准备工作已经完成,现在开始正式使用RecyclerView,在布局中的添加RecyclerView,在这里,和往常添加的控件稍微不同,这里添加控件不能只是给出RecyclerView的名字,要将完整的包路径给出

 <android.support.v7.widget.RecyclerView        android:id="@+id/notes_title_recycler_view"        android:layout_width="match_parent"        android:layout_height="match_parent"/>

好,到这里,控件添加进来,一开始说它的功能类似于ListView,接下来当然时去新建一个子布局(item),下面这一长串的代码就是我定义的子布局,其中里面有一个自定义控件

com.example.haha.note.Note_delete(实现侧滑的重要控件,下面会详细介绍),从这里就可以看出如果不是安卓SDK内置的控件,要使用统一要给出完整的路径

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="80dp"    android:orientation="vertical"    android:background="@drawable/diy_frame"    android:layout_marginTop="10dp">    <com.example.haha.note.Note_delete        android:layout_width="match_parent"        android:layout_height="match_parent"        android:scrollbars="none">        <LinearLayout            android:layout_width="wrap_content"            android:layout_height="match_parent"            android:orientation="horizontal">    <RelativeLayout        android:id="@+id/left"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:background="@drawable/item_bg">    <TextView        android:id="@+id/notes_title"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_gravity="center"        android:gravity="center_vertical"        android:maxLines="1"        android:ellipsize="end"        android:textSize="18sp"        android:paddingLeft="10dp"        android:paddingRight="10dp"        android:paddingTop="15dp"        android:paddingBottom="15dp"        />    </RelativeLayout>        <RelativeLayout            android:id="@+id/right"            android:layout_width="200dp"            android:layout_height="match_parent"            android:layout_toRightOf="@+id/left">            <ImageView                android:id="@+id/edit_note"                android:layout_width="100dp"                android:layout_height="match_parent"                android:layout_gravity="center"                android:gravity="center"                android:src="@drawable/editor"               />            <ImageView                android:id="@+id/tv_delete"                android:layout_width="match_parent"                android:layout_height="match_parent"                android:layout_gravity="center"                android:gravity="center"                android:layout_toRightOf="@+id/edit_note"                android:src="@drawable/cut"                />        </RelativeLayout>        </LinearLayout></com.example.haha.note.Note_delete></LinearLayout>

子布局定义完后,接下来还是老步骤,它和ListView一样需要一个适配器,现在我们去创建一个java类让它继承RecyclerView.Adapter,下面这一大段只需要理解 onCreateViewHolder()、onBindViewHolder()和getItemCount(),因为继承自RecyclerView.Adapter就得重写这3个方法

class NoteAdapter extends RecyclerView.Adapter<NoteAdapter.ViewHolder>{        private List<notes> mNoteList;        class ViewHolder extends RecyclerView.ViewHolder{            TextView noteTitleText;            ImageView deleteItem;            public  ViewHolder(View view){                super(view);                noteTitleText=(TextView) view.findViewById(R.id.notes_title);                deleteItem=(ImageView)view.findViewById(R.id.tv_delete);            }        }        public NoteAdapter(List<notes> notesList){            mNoteList=notesList;        }        @Override        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){      //加载子布局时调用            View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.notes_item,parent,false);            item_edit=(ImageView) view.findViewById(R.id.edit_note);            item_delete=(ImageView) view.findViewById(R.id.tv_delete);           final  ViewHolder holder=new ViewHolder(view);          item_edit.setOnClickListener(new View.OnClickListener() {            public void onClick(View view) {     //RecyclerView的点击事件,这段代码和本文章无太大关系,所以可以忽略                notes note=mNoteList.get(holder.getAdapterPosition());               if(isTwoPane){                    NotesContentFragment notesContentFragment=(NotesContentFragment) getFragmentManager().findFragmentById(R.id.notes_content_fragment);                    notesContentFragment.refresh(note.getTitle(),note.getContent());                }else {                    notesContentActivity.actionStart(getActivity(),note.getTitle(),note.getContent());               }            }        });            return  holder;        }        /*            添加删除Item         */        public void delete_item( List<notes> mNoteList,int position){            mNoteList.remove(position);            notifyItemRemoved(position);            notifyItemRangeChanged(position,mNoteList.size()-position);        }        public void onBindViewHolder(final ViewHolder holder, final int position){   
        //由onCreateViewHolder返回一个对应子布局的holder,再由onBindViewHolder进行赋值            notes note=mNoteList.get(position);            holder.noteTitleText.setText(note.getTitle());            holder.deleteItem.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View view) {                    delete_item(mNoteList,position);                }            });        }        public int getItemCount(){            return mNoteList.size();        }    }

适配器类写好之后,接下来介绍实现侧滑的重要控件,com.example.haha.note.Note_delete 。这是个自定义控件,我们来看下它的代码

package com.example.haha.note;import android.content.Context;import android.util.AttributeSet;import android.util.TypedValue;import android.view.MotionEvent;import android.view.ViewGroup;import android.widget.HorizontalScrollView;import android.widget.LinearLayout;import static android.R.id.content;/** * Created by haha on 2017/9/12. */public class Note_delete extends HorizontalScrollView{    private int mScreenWidth;  //屏幕宽度    private int mMenuWidth;//菜单宽度    private  boolean once;    public Note_delete(Context context, AttributeSet attrs){        super(context,attrs);        mScreenWidth=ScreenUtil.getScreenWidth(context);//由安卓内置类ScreenUtil获取屏幕宽度 ,注意要写一个ScreenUtil类    }    protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec){        /*        * 自定义类是继承自HorizontalScrollView,那么意图就非常明显,就是要利用父类的水平滑动效果        * 而HorizontalScrollView这个控件只允许放一个子控件,一般来说,一个控件是远远不够,那么就        * 直接设置一个线性布局,然后再在线性布局里放置任意我们想放的控件,这样就解决了控件数量的        * 限制,所以下面的getChildAt(0)让对应的就是设置的线性布局,获取对象,然后再由该对象获取布        * 局中的控件对象,这样所有控件对象都能取到*/            LinearLayout wrapper=(LinearLayout) getChildAt(0);            ViewGroup menu=(ViewGroup) wrapper.getChildAt(1);//获取线性布局中的第二个控件对象            mMenuWidth=mScreenWidth/2;            menu.getLayoutParams().width=mMenuWidth;//给获取的控件对象进行属性设置        super.onMeasure(widthMeasureSpec,heightMeasureSpec);    }    public boolean onTouchEvent(MotionEvent ev){        int action=ev.getAction();        switch (action){            case MotionEvent.ACTION_UP://触碰抬起,判断手指滑动距离                int scrollX=getScrollX();                if(scrollX > mMenuWidth/4)                    this.smoothScrollTo(mMenuWidth,0);                else                    this.smoothScrollTo(0,0);                return true;        }        return super.onTouchEvent(ev);    }}


写ScreenUtil类,用于获取屏幕高宽度

package com.example.haha.note;import android.content.Context;import android.util.DisplayMetrics;import android.view.WindowManager;/** * Created by haha on 2017/9/12. */public class ScreenUtil {    private ScreenUtil(){        throw new UnsupportedOperationException("cannot be instantiated");    }    //获得屏幕高度    public static int getScreenHeight(Context context){        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);        DisplayMetrics outMetrics = new DisplayMetrics();        wm.getDefaultDisplay().getMetrics(outMetrics);        return outMetrics.heightPixels;    }    //获得屏幕宽度    public static int getScreenWidth(Context context) {        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);        DisplayMetrics outMetrics = new DisplayMetrics();        wm.getDefaultDisplay().getMetrics(outMetrics);        return outMetrics.widthPixels;    }}


最后,初始化数据,开始使用RecyclerView+HorizontalScrollView

这里我实现了Fragment,实际上和文章有关的代码仅仅需要看注释1-3的代码和初始化方法就行

public class NotesTitleFragment extends Fragment {    ImageView item_delete;    ImageView  item_edit;    TextView  item_add;   private boolean isTwoPane;    public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){        View view=inflater.inflate(R.layout.notes_title_frag,container,false);//这不是活动类,所以必须将布局引进        RecyclerView noteTitleRecyclerView=(RecyclerView) view.findViewById(R.id.notes_title_recycler_view);//1        LinearLayoutManager layoutManager=new LinearLayoutManager(getActivity());//2        noteTitleRecyclerView.setLayoutManager(layoutManager);//3        /*        * 上面注释着1-3的代码就是使用RecyclerView的核心        * 1.获取对象        * 2.这句代码就能体现RecyclerView的强大之处,这里用的是线性布局管理,说白了就是控制RecyclerView里的item布局,        *   那么它当然不只有这一种布局方式,还有瀑布式布局等,而相比ListView只能是垂直摆放来说,RecyclerView简直是        *   强大到炸,非常灵活        * 3.对RecyclerView对象进行布局设置*/        final NoteAdapter adapter=new NoteAdapter(getNote());        noteTitleRecyclerView.setAdapter(adapter);        item_add=view.findViewById(R.id.tv_add);        item_add.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                addItem(adapter);            }        });        return view;    }    public void addItem(NoteAdapter noteAdapter){//实现动态添加一个item        noteAdapter.notifyItemInserted(1);    }    private List<notes> getNote(){        List<notes> notesList=new ArrayList<>();        for(int i=1;i<=50;i++){            notes note=new notes();            note.setTitle("这里有位置,快来开始你的事件记录吧ԅ(¯﹃¯ԅ)" );            note.setContent("美好的一天,怎能忍心错过不进行记录呢(「・ω・)「嘿");            notesList.add(note);        }        return notesList;    }
上面是核心的代码,并不完整,但实现图中的效果,这些就够了,非常简单!如有错误,希望大家多多指教!本文章内容素材部分取自郭霖《第一行代码》


阅读全文
0 0
原创粉丝点击