1. 程式人生 > >RecyclerView+CardView+共享元素+調色盤的綜合demo

RecyclerView+CardView+共享元素+調色盤的綜合demo

提到,Android L版本中新增了RecyclerView、CardView 、Palette。RecyclerView、CardView為用於顯示覆雜檢視的新增Widget。Palette作為調色盤類,可以讓你從影象中提取突出的顏色。RecyclerView 是Android5.0之後新出來的一個控制元件,它以後將會逐漸替代ListView的用法。相對於listView來說,RecyclerView的功能比它更強大,recyclerView能夠實現listView和gridView的效果,還有瀑布流的效果。RecyclerView相對於ListView來說它標準化了ViewHolder,在ListView中複用的是contentView,而在recyclerView中是把ViewHolder作為快取的單位了,然後contentView

作為ViewHolder的成員變數保持在ViewHolder中,所以ListView中的getView方法被替換成了onCreateViewHolder方法。而我認為唯一美中不足的是RecyclerView不提供setOnItemClickListener方法,所以我們需要在它的介面卡中手動新增一個回撥監聽事件來處理它的Item點選事件。

不多說,具體的看程式碼:

工程結構:

  

MainActivity類
package com.bobge.cardgriddemo;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


public class MainActivity extends ActionBarActivity implements MyAdapter.onItemClickListener{
    private RecyclerView recyclerView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView= (RecyclerView) findViewById(R.id.recyclerView);
        //網格佈局管理器
        StaggeredGridLayoutManager manager=new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(manager);
       // WaterfallEntries entries=new WaterfallEntries();
        try {
<span style="white-space:pre">		</span>//作為recyclerView資料來源<span style="font-family: SimSun;">WaterfallEntries是圖文混搭的實體類</span>
            List<WaterfallEntries> entries=new ArrayList<WaterfallEntries>();
            String[] list=getAssets().list("");//得到資產目錄的所有圖片名稱
            int i=0;
            for (String s:list)
            {
                if(s.endsWith(".jpg")){
                    entries.add(i,new WaterfallEntries(s,String.format("第%02d組資料",i)));
                    i++;
                    Log.i("Assets", s);
                }
                else{
                    Log.d("Assets",s);
                }
            }
            MyAdapter adapter=new MyAdapter(this,entries);
            adapter.setItemClickListener(this);//給介面卡新增點選事件,回撥處理
            recyclerView.setAdapter(adapter);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onItemClick(int position, View v,WaterfallEntries entries) {
        Intent intent=new Intent();
        intent.setClass(this, SharedActivity.class);
        intent.putExtra("image", entries.getPicName());
        intent.putExtra("text", entries.getText());
        ImageView imageView= (ImageView) v.findViewById(R.id.image_waterfall);
        //android5.0以上的api有這些方法(在Android5.0以下的手機執行會報錯,只有在5.0之上才能正確執行並且看到效果)
     //   ActivityOptions options=ActivityOptions.makeSceneTransitionAnimation(this,Pair.create(textView,"textView"),Pair.create(textView,"textView"));
     //   ActivityOptions options=ActivityOptions.makeSceneTransitionAnimation(this, imageView, "imageView_share");
     //   startActivity(intent,options.toBundle());
        //向下相容(在Android5.0以下看不到共享元素的那種效果,但是在5.0以下的手機上能正常執行)
        ActivityOptionsCompat optionsCompat=ActivityOptionsCompat.makeSceneTransitionAnimation(this, imageView, "imageView_share");
        startActivity(intent,optionsCompat.toBundle());
    }
}
MyAdapter類:
package com.bobge.cardgriddemo;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.support.v7.graphics.Palette;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * Created by aaa on 15-5-20.
 */
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> implements View.OnClickListener {
    private Context context;
    private List<WaterfallEntries> list;
    private onItemClickListener itemClickListener;//ItemView的監聽器
    private RecyclerView recyclerView;
    public MyAdapter(Context context, List<WaterfallEntries> entries) {
        this.context=context;
        this.list=entries;
    }

    public void setItemClickListener(onItemClickListener itemClickListener) {
        this.itemClickListener = itemClickListener;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int i) {
        View view= LayoutInflater.from(context).inflate(R.layout.item,parent,false);
        view.setOnClickListener(this);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int postion) {
        String picName=list.get(postion).getPicName();
        InputStream open=null;
        try {
            open = context.getAssets().open(picName);
            Bitmap bm= BitmapFactory.decodeStream(open);
            //這個方法是22.1.1時出現的,推薦使用
            Palette palette = Palette.from(bm).generate();//得到調色盤
            Palette.Swatch vibrantSwatch=palette.getVibrantSwatch();//有活力的配色方案
            if(vibrantSwatch == null){
                viewHolder.card.setCardBackgroundColor(Color.WHITE);
                viewHolder.text.setTextColor(Color.BLACK);
            }else {
                viewHolder.card.setCardBackgroundColor(vibrantSwatch.getRgb());
                viewHolder.text.setTextColor(vibrantSwatch.getTitleTextColor());
            }
            viewHolder.image.setImageBitmap(bm);
            viewHolder.text.setText(list.get(postion).getText());
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (open != null) {
                try {
                    open.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        this.recyclerView=recyclerView;
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    @Override
    public void onClick(View v) {
        if (itemClickListener != null && recyclerView != null){
            //recyclerView 21以下使用, 22時作廢
           // int position = recyclerView.getChildPosition(v);
            //22時用些方法替換上面的方法
            int position = recyclerView.getChildAdapterPosition(v);
            itemClickListener.onItemClick(position,v,list.get(position));
        }
    }

    public static class ViewHolder extends RecyclerView.ViewHolder{

        private ImageView image;
        private TextView text;
        private CardView card;
        public ViewHolder(View itemView) {
            super(itemView);
            image= (ImageView) itemView.findViewById(R.id.image_waterfall);
            text= (TextView) itemView.findViewById(R.id.text);
            card= (CardView) itemView.findViewById(R.id.card);
        }

    }
    public interface onItemClickListener{
        void onItemClick(int position,View v,WaterfallEntries entries);
    }
}
<pre name="code" class="java" style="color: rgb(50, 51, 51); font-size: 18px; line-height: 26px;"><strong>WaterfallEntries 實體類(用來存放圖片文和textView)</strong>
package com.bobge.cardgriddemo;

/**
 * Created by aaa on 15-5-20.
 */
public class WaterfallEntries {
    private String text;
    private String picName;

    public WaterfallEntries() {
    }

    public WaterfallEntries(String picName, String text) {
        this.text = text;
        this.picName = picName;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public String getPicName() {
        return picName;
    }

    public void setPicName(String picName) {
        this.picName = picName;
    }
}

佈局檔案:

MAinActivity的佈局檔案:

<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
activity_shared的佈局檔案:
<com.bobge.cardgriddemo.MyImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageView_share"
android:layout_centerInParent="true"
android:transitionName="imageView_share"
android:layout_centerHorizontal="true"
android:background="@drawable/bb"
/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="@+id/textView_share"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"/>
item的佈局檔案:cardView能夠實現帶圓角的矩形
<!--?xml version=1.0 encoding=utf-8?-->
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/card"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
card_view:cardCornerRadius="5dp">

    <LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
        <com.bobge.cardgriddemo.MyImageView
android:id="@+id/image_waterfall"
android:layout_height="wrap_content"
android:transitionName="imageView_share"
android:layout_width="wrap_content"
/>
        <TextView
android:clickable="true"
android:gravity="center"
android:id="@+id/text"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textColor="#000"
android:textSize="20sp"/>
    </LinearLayout>

</android.support.v7.widget.CardView>

自定義的iamgeView控制元件:能夠防止圖片顯示在CardView中出現空白。
package com.bobge.cardgriddemo;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;

/**
 * Created by aaa on 15-5-20.
 */
public class MyImageView extends ImageView {

    public MyImageView(Context context) {
        super(context);
    }

    public MyImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        Drawable drawable = getDrawable();
        if (drawable == null) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        } else {
            int size = MeasureSpec.getSize(widthMeasureSpec);
            int hSize = size * drawable.getIntrinsicHeight() / drawable.getIntrinsicWidth();//得到固有的高度和寬度
            setMeasuredDimension(size, hSize);//只能在onMeasure總呼叫此方法,設定測量好的寬高
        }

    }
}

共享元素的跳轉頁面:
package com.bobge.cardgriddemo;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import java.io.IOException;
import java.io.InputStream;


public class SharedActivity extends ActionBarActivity implements View.OnClickListener {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_shared);
        Intent intent=getIntent();
        String image=intent.getStringExtra("image");
        String text=intent.getStringExtra("text");
        ImageView imageView_share= (ImageView) findViewById(R.id.imageView_share);
        TextView textView_share= (TextView) findViewById(R.id.textView_share);
        try {
            InputStream open=this.getAssets().open(image);
            Bitmap bitmap= BitmapFactory.decodeStream(open);
            imageView_share.setImageBitmap(bitmap);
            textView_share.setText(text);
        } catch (IOException e) {
            e.printStackTrace();
        }
        imageView_share.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
       // this.finishAfterTransition();
        ActivityCompat.finishAfterTransition(this);//相容5.0以下的手機,執行不會出錯,但是隻有在5.0以上的手機才能看到共享元素回退的效果
    }
}

效果圖: