Android RecyclerView+CardView实现瀑布流效果

所需要的库及库工程

库:

android-support-v7-recyclerview.jar :v21.x

android-support-v4.jar :v21.x

库工程:

android-support-v7-appcompat:v21.x

android-support-v7-cardview

 

注意:cardView必须使用库工程,而不能使用jar包,原因是其引用了自定义属性

但是,如果必须要使用cardView而不导入工程,建议使用cardview源码,主要步骤如下

①将自定义attr,color,dimens,styles拷贝至工程目录下

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

②修改源码中的 import android.support.v7.cardview.R; 成当前工程的R资源

③认真完成以上2步骤

 

效果预览

 

Activity文件

?
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package  st.app.base.rcp;
 
import  java.lang.reflect.Method;
import  java.util.ArrayList;
import  java.util.List;
 
import  android.os.Bundle;
import  android.support.v7.app.ActionBarActivity;
import  android.support.v7.internal.view.menu.MenuBuilder;
import  android.support.v7.widget.RecyclerView;
import  android.support.v7.widget.StaggeredGridLayoutManager;
import  android.support.v7.widget.Toolbar;
import  android.util.Log;
import  android.view.Menu;
import  android.view.MenuItem;
import  android.view.View;
 
public  class  WaterfallActivity  extends  ActionBarActivity {
     private  Toolbar mToolbar;
     private  RecyclerView mRecyclerView;
     private  List<String> mDatas =  null ;
     
     private  SimpleRecyclerCardAdapter mSimpleRecyclerAdapter;
     
     @Override
     protected  void  onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         
         mToolbar = (Toolbar) findViewById(R.id.toolbar);  
         mRecyclerView = (RecyclerView) findViewById(R.id.app_recyclerview);
         
         initAppToolBar();
         initDataAndView();
     }
     
     private  void  initDataAndView() 
     {
         mDatas =  new  ArrayList<String>();
         for ( int  i= 'A' ;i<= 'z' ;i++)
         {
             mDatas.add(String.valueOf(( char )i));
         }
         mSimpleRecyclerAdapter =  new  SimpleRecyclerCardAdapter( this , mDatas);
         mRecyclerView.setAdapter(mSimpleRecyclerAdapter);
         //设置网格布局管理器
         mRecyclerView.setLayoutManager( new  StaggeredGridLayoutManager( 3 , StaggeredGridLayoutManager.VERTICAL));
         mSimpleRecyclerAdapter.setOnItemActionListener( new  SimpleRecyclerCardAdapter.OnItemActionListener() {
             
             @Override
             public  boolean  onItemLongClickListener(View v,  int  pos)
             {
                 Toast.makeText(activity,  "-长按-" +pos, Toast.LENGTH_SHORT).show();
                 return  false ;
             }
             @Override
             public  void  onItemClickListener(View v,  int  pos) {
                 Toast.makeText(activity,  "-单击-" +pos, Toast.LENGTH_SHORT).show();
             }
         });
         
     }
     /**
      * init app bar
      */
     private  void  initAppToolBar()
     {
         mToolbar.setNavigationIcon(R.drawable.ktv_ic_main_hot_pressed);
         mToolbar.setTitle( "Rocko" ); // 标题的文字需在setSupportActionBar之前,不然会无效   
         mToolbar.inflateMenu(R.menu.main);
         setShortcutsVisible(mToolbar.getMenu());
         mToolbar.setOnMenuItemClickListener( new  Toolbar.OnMenuItemClickListener() {  
             @Override  
             public  boolean  onMenuItemClick(MenuItem item) {  
                 switch  (item.getItemId()) {  
                 case  R.id.action_settings:  
                     break ;  
                 case  R.id.action_mail:  
                     break ;  
                 case  R.id.action_plus:
                    break ;
                 default :  
                     break ;  
                 }  
                 return  true ;  
             }  
         }); 
         
         mToolbar.setNavigationOnClickListener( new  View.OnClickListener() {
             
             @Override
             public  void  onClick(View v) {
                 Log.e( "Navigation" "Click" );
             }
         });
     }
     private  void  setShortcutsVisible(Menu menu)
     {
         if (MenuBuilder. class .isInstance(menu))
         {
             MenuBuilder builder = (MenuBuilder) menu;
             builder.setShortcutsVisible( true );
             try  {
                     Method m = menu.getClass().getDeclaredMethod(
                             "setOptionalIconsVisible" , Boolean.TYPE);
                     m.setAccessible( true );
                     m.invoke(builder,  true );
                 catch  (Exception ie) {
             }
         }
     }
}

Adapter+ViewHolder

?
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import  java.util.ArrayList;
import  java.util.List;
 
import  android.content.Context;
import  android.support.v7.widget.RecyclerView;
import  android.support.v7.widget.RecyclerView.ViewHolder;
import  android.view.LayoutInflater;
import  android.view.View;
import  android.view.ViewGroup;
import  android.widget.ImageView;
import  android.widget.TextView;
public  class  SimpleRecyclerCardAdapter   extends  RecyclerView.Adapter<SimpleCardViewHolder>{
 
     private  Context mCtx;
     private  LayoutInflater mInflater;
     private  final  List<String> mDataSource =  new  ArrayList<String>();
     private  OnItemActionListener mOnItemActionListener; 
     
     public  SimpleRecyclerCardAdapter(Context mCtx, List<String> dataList) {
         super ();
         this .mCtx = mCtx;
         mInflater = LayoutInflater.from(mCtx);
         this .mDataSource.addAll(dataList);
     }
     @Override
     public  int  getItemCount() {
         return  mDataSource.size();
     }
     @Override
     public  void  onBindViewHolder( final  SimpleCardViewHolder viewHolder,   int  i) {
         viewHolder.itemTv.setText(mDataSource.get(i));
         int  resId = mCtx.getResources().getIdentifier( "img_" +i,  "drawable" , mCtx.getPackageName());
         if (resId!= 0 )
         {
             viewHolder.itemIv.setImageResource(resId);
         }
         if (mOnItemActionListener!= null )
         {
             viewHolder.itemView.setOnClickListener( new  View.OnClickListener() {
                 
                 @Override
                 public  void  onClick(View v) {
                        //注意这里必须使用viewHolder.getPosition()而不能用i,因为为了保证动画,没有使用NotifyDatasetChanged更新位置数据
                     mOnItemActionListener.onItemClickListener(v,viewHolder.getPosition()); 
                 }
             });
             viewHolder.itemView.setOnLongClickListener( new  View.OnLongClickListener() {
                 @Override
                 public  boolean  onLongClick(View v) {
                  //注意这里必须使用viewHolder.getPosition()而不能用i,因为为了保证动画,没有使用NotifyDatasetChanged更新位置数据
                     return  mOnItemActionListener.onItemLongClickListener(v, viewHolder.getPosition());
                 }
             });
         }
     }
     @Override
     public  SimpleCardViewHolder onCreateViewHolder(ViewGroup viewgroup,  int  i) {
         
         View v =  mInflater.inflate(R.layout.simple_card_item, viewgroup, false );
         SimpleCardViewHolder simpleViewHolder =  new  SimpleCardViewHolder(v);
         simpleViewHolder.setIsRecyclable( true );
         
         return  simpleViewHolder;
     }
     /**********定义点击事件**********/
     public    interface  OnItemActionListener
     {
         public    void  onItemClickListener(View v, int  pos);
         public    boolean  onItemLongClickListener(View v, int  pos);
     }
     public  void  setOnItemActionListener(OnItemActionListener onItemActionListener) {
         this .mOnItemActionListener = onItemActionListener;
     }
}
class  SimpleCardViewHolder  extends  ViewHolder
{
     public  TextView itemTv;
     public  ImageView itemIv;
 
     public  SimpleCardViewHolder(View layout) {
         super (layout);
         itemTv = (TextView) layout.findViewById(R.id.item_title);
         itemIv = (ImageView) layout.findViewById(R.id.item_img);
     }
}

布局文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"
     xmlns:app= "http://schemas.android.com/apk/res-auto"
     xmlns:tools= "http://schemas.android.com/tools"
     android:layout_width= "match_parent"
     android:layout_height= "match_parent"
     android:orientation= "vertical"
     android:background= "@android:color/white"
     tools:context= "st.app.base.rcp.MainActivity"  >
     <android.support.v7.widget.Toolbar
         android:id= "@+id/toolbar"
         android:layout_width= "match_parent"
         android:layout_height= "wrap_content"
         android:background= "@color/material_deep_teal_500"
         android:minHeight= "?attr/actionBarSize"
         app:popupTheme= "@style/AppBarTheme"
         app:theme= "@style/ThemeOverlay.AppCompat.ActionBar"  >
     </android.support.v7.widget.Toolbar>
     <android.support.v7.widget.RecyclerView
         android:id= "@+id/app_recyclerview"
         android:layout_width= "match_parent"
         android:layout_height= "match_parent"
          />
 
</LinearLayout>

item布局文件

?
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
<?xml version= "1.0"  encoding= "utf-8" ?>
<android.support.v7.widget.CardView 
     xmlns:android= "http://schemas.android.com/apk/res/android"  
     xmlns:app= "http://schemas.android.com/apk/res-auto"
     android:id= "@+id/cardview"  
     android:layout_margin= "0dp"  
     android:layout_height= "83dp"
     app:cardBackgroundColor= "@android:color/white" 
     app:cardCornerRadius= "5dp"  
     app:cardElevation= "5dp"
     app:contentPadding= "5dip"
     android:layout_width= "match_parent"  >
     <RelativeLayout  
         android:layout_width= "match_parent"  
         android:layout_height= "match_parent"
         >  
         <ImageView  
             android:id= "@+id/item_img"  
             android:layout_width= "match_parent"  
             android:layout_height= "wrap_content"  
             android:layout_centerHorizontal= "true"  
             android:scaleType= "fitCenter"  />  
         <TextView  
             android:id= "@+id/item_title"  
             android:layout_width= "wrap_content"  
             android:layout_height= "wrap_content"  
             android:layout_below= "@+id/item_img"  
             android:layout_centerHorizontal= "true"  
             android:textColor= "@color/material_deep_teal_500"
             android:paddingLeft= "@dimen/activity_horizontal_margin"  
             android:paddingRight= "@dimen/activity_horizontal_margin"  />  
     </RelativeLayout>  
</android.support.v7.widget.CardView>

主题样式

AppBarBaseTheme

?
1
2
3
4
<style name= "Theme.AppCompat.NoActionBar" >
         <item name= "windowActionBar" > false </item>
         <item name= "android:windowNoTitle" > true </item>
     </style>

styles

 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<style name= "AppBarTheme"  parent= "ThemeOverlay.AppCompat.Light" >
         <item name= "actionDropDownStyle" > @style /AppBaseToolBarMenuDropDownStyle</item>
         <item name= "actionOverflowMenuStyle" > @style /AppBaseToolbarOverflowMenuStyle</item>
         <item name= "android:textColor" > @android :color/white</item>
     </style>
     <style name= "AppBaseToolBarMenuDropDownStyle"  parent= "@style/Base.Widget.AppCompat.Spinner.DropDown.ActionBar" >
         <item name= "overlapAnchor" > false </item>
         <item name= "android:popupBackground" > @color /material_deep_teal_500</item>
         <item name= "android:dropDownHorizontalOffset" >-4dip</item>
     </style>
      
     <style name= "AppBaseToolbarOverflowMenuStyle"  parent= "@style/Widget.AppCompat.Light.PopupMenu.Overflow" >
         <item name= "overlapAnchor" > false </item>
         <item name= "android:popupBackground" > @color /material_deep_teal_500</item>
         <item name= "android:textColorPrimary" > @android :color/white</item>
     </style>

附加一点Palettel小知识,该工具用于位图取色,使用环境为换肤,换title,或者取色(取色可以动态截图的方式)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Palette.generateAsync(bitmap,  
                 new  Palette.PaletteAsyncListener() {  
             @Override  
             public  void  onGenerated(Palette palette) {  
                  Palette.Swatch vibrant =  
                          palette.getVibrantSwatch();  
                   if  (vibrant !=  null ) {  
                     
                           int  rgb = vibrant.getRgb();
                           int  titleTextColor = vibrant.getTitleTextColor();
                           int  bodyTextColor = vibrant.getBodyTextColor();
                   }  
             }  
         });

 

git  demo address:https://github.com/oasis2008/PinterestListView

猜你喜欢

转载自wyj365372704.iteye.com/blog/2263288