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

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

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

  先上效果图

 

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


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

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


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

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

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


  
  
  1. <LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"
  2. android:layout_width= "match_parent"
  3. android:layout_height= "80dp"
  4. android:orientation= "vertical"
  5. android:background= "@drawable/diy_frame"
  6. android:layout_marginTop= "10dp">
  7. <com.example.haha.note.Note_delete
  8. android:layout_width= "match_parent"
  9. android:layout_height= "match_parent"
  10. android:scrollbars= "none">
  11. <LinearLayout
  12. android:layout_width= "wrap_content"
  13. android:layout_height= "match_parent"
  14. android:orientation= "horizontal">
  15. <RelativeLayout
  16. android:id= "@+id/left"
  17. android:layout_width= "match_parent"
  18. android:layout_height= "match_parent"
  19. android:background= "@drawable/item_bg">
  20. <TextView
  21. android:id= "@+id/notes_title"
  22. android:layout_width= "match_parent"
  23. android:layout_height= "match_parent"
  24. android:layout_gravity= "center"
  25. android:gravity= "center_vertical"
  26. android:maxLines= "1"
  27. android:ellipsize= "end"
  28. android:textSize= "18sp"
  29. android:paddingLeft= "10dp"
  30. android:paddingRight= "10dp"
  31. android:paddingTop= "15dp"
  32. android:paddingBottom= "15dp"
  33. />
  34. </RelativeLayout>
  35. <RelativeLayout
  36. android:id= "@+id/right"
  37. android:layout_width= "200dp"
  38. android:layout_height= "match_parent"
  39. android:layout_toRightOf= "@+id/left">
  40. <ImageView
  41. android:id= "@+id/edit_note"
  42. android:layout_width= "100dp"
  43. android:layout_height= "match_parent"
  44. android:layout_gravity= "center"
  45. android:gravity= "center"
  46. android:src= "@drawable/editor"
  47. />
  48. <ImageView
  49. android:id= "@+id/tv_delete"
  50. android:layout_width= "match_parent"
  51. android:layout_height= "match_parent"
  52. android:layout_gravity= "center"
  53. android:gravity= "center"
  54. android:layout_toRightOf= "@+id/edit_note"
  55. android:src= "@drawable/cut"
  56. />
  57. </RelativeLayout>
  58. </LinearLayout>
  59. </com.example.haha.note.Note_delete>
  60. </LinearLayout>

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


  
  
  1. class NoteAdapter extends RecyclerView.Adapter<NoteAdapter.ViewHolder>{
  2. private List<notes> mNoteList;
  3. class ViewHolder extends RecyclerView.ViewHolder{
  4. TextView noteTitleText;
  5. ImageView deleteItem;
  6. public ViewHolder(View view){
  7. super(view);
  8. noteTitleText=(TextView) view.findViewById(R.id.notes_title);
  9. deleteItem=(ImageView)view.findViewById(R.id.tv_delete);
  10. }
  11. }
  12. public NoteAdapter(List<notes> notesList){
  13. mNoteList=notesList;
  14. }
  15. @Override
  16. public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){ //加载子布局时调用
  17. View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.notes_item,parent, false);
  18. item_edit=(ImageView) view.findViewById(R.id.edit_note);
  19. item_delete=(ImageView) view.findViewById(R.id.tv_delete);
  20. final ViewHolder holder= new ViewHolder(view);
  21. item_edit.setOnClickListener( new View.OnClickListener() {
  22. public void onClick(View view) { //RecyclerView的点击事件,这段代码和本文章无太大关系,所以可以忽略
  23. notes note=mNoteList.get(holder.getAdapterPosition());
  24. if(isTwoPane){
  25. NotesContentFragment notesContentFragment=(NotesContentFragment) getFragmentManager().findFragmentById(R.id.notes_content_fragment);
  26. notesContentFragment.refresh(note.getTitle(),note.getContent());
  27. } else {
  28. notesContentActivity.actionStart(getActivity(),note.getTitle(),note.getContent());
  29. }
  30. }
  31. });
  32. return holder;
  33. }
  34. /*
  35. 添加删除Item
  36. */
  37. public void delete_item( List<notes> mNoteList,int position){
  38. mNoteList.remove(position);
  39. notifyItemRemoved(position);
  40. notifyItemRangeChanged(position,mNoteList.size()-position);
  41. }
  42. public void onBindViewHolder(final ViewHolder holder, final int position){

  
  
  1. //由onCreateViewHolder返回一个对应子布局的holder,再由onBindViewHolder进行赋值
  2. notes note=mNoteList.get(position);
  3. holder.noteTitleText.setText(note.getTitle());
  4. holder.deleteItem.setOnClickListener( new View.OnClickListener() {
  5. @Override
  6. public void onClick(View view) {
  7. delete_item(mNoteList,position);
  8. }
  9. });
  10. }
  11. public int getItemCount(){
  12. return mNoteList.size();
  13. }
  14. }

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

扫描二维码关注公众号,回复: 3664183 查看本文章

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


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


  
  
  1. package com.example.haha.note;
  2. import android.content.Context;
  3. import android.util.DisplayMetrics;
  4. import android.view.WindowManager;
  5. /**
  6. * Created by haha on 2017/9/12.
  7. */
  8. public class ScreenUtil {
  9. private ScreenUtil(){
  10. throw new UnsupportedOperationException( "cannot be instantiated");
  11. }
  12. //获得屏幕高度
  13. public static int getScreenHeight(Context context){
  14. WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
  15. DisplayMetrics outMetrics = new DisplayMetrics();
  16. wm.getDefaultDisplay().getMetrics(outMetrics);
  17. return outMetrics.heightPixels;
  18. }
  19. //获得屏幕宽度
  20. public static int getScreenWidth(Context context) {
  21. WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
  22. DisplayMetrics outMetrics = new DisplayMetrics();
  23. wm.getDefaultDisplay().getMetrics(outMetrics);
  24. return outMetrics.widthPixels;
  25. }
  26. }


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

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


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


阅读更多

猜你喜欢

转载自blog.csdn.net/L1083419193/article/details/83148691