Android RecyclerView&CardView实现瀑布流效果

原创
2015/08/12 20:54
阅读数 3.2W

所需要的库及库工程

库:

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拷贝至工程目录下

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

③认真完成以上2步骤


效果预览


Activity文件

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

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);
	}
}

布局文件

<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布局文件

<?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

<style name="Theme.AppCompat.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="android:windowNoTitle">true</item>
    </style>

styles

 
<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>
        <!--溢出菜单按钮(ActionBar溢出菜单,即最后一个按钮)-->
        <item name="actionOverflowButtonStyle">@style/AppBaseToolbarOverflowButtonStyle</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>
        <!--ActionBar Menu颜色-->
        <item name="android:textColorPrimary">@android:color/white</item>
    </style>
    <style name="AppBaseToolbarOverflowButtonStyle" parent="@style/Widget.AppCompat.Light.ActionButton.Overflow">
    <item name="android:src">@drawable/abc_ic_menu_moreoverflow_mtrl_alpha</item>
</style>

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

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();
		          }  
		    }  
		});


展开阅读全文
打赏
2
15 收藏
分享
加载中
求楼主给下源码!!!ybj366533@qq.com2
2016/09/12 20:00
回复
举报
求楼主给下源码!!!ybj366533@qq.com2
2016/09/12 19:59
回复
举报
求楼主给下源码!!!ybj366533@qq.com2
2016/09/12 19:59
回复
举报
源码能发一下吗?www.zhangke11@qq.com
非常感谢!!!
2016/08/01 14:57
回复
举报
楼主,能发一下源码吗?chenjin5525@126.com0非常感谢
2016/03/23 16:12
回复
举报
chenjin5525@126.com
2016/03/23 16:12
回复
举报
楼主,能发一下源码吗?
2016/03/23 16:12
回复
举报
该评论暂时无法显示,详情咨询 QQ 群:912889742
该评论暂时无法显示,详情咨询 QQ 群:912889742
楼主,98求源码~~~54急求54965403521@qq.com
2016/03/10 15:39
回复
举报
更多评论
打赏
14 评论
15 收藏
2
分享
返回顶部
顶部