今天要來說說RecyclerView+Shared Element的應用
...如果就著功能描述來說,就是"點擊清單內的圖片元件,並使之詳細顯示"這樣吧!
如下Gif操作
當時我在還不知道這種操作的關鍵字時,我是用這段字搜尋的
"RecyclerView點擊放大"
(゚д゚;)(゚д゚;)(゚д゚;)(゚д゚;)(゚д゚;)
好在還真的有人這樣寫XD,於是也很快就知道了"Shared Element"這個詞
總而言之言而總之,就是這樣了解到了這個東西。
那閒聊到這,馬上來聊這個元件吧!
Github
->https://github.com/thumbb13555/SharedElementDemo/tree/master
1. 核心程式碼
基本上,雖然仿間給了這項功能叫做Shared Element,但是其本質上就是一個"Activity的跳轉"而已(・∀・)
...然後再加上跳轉動畫這樣(笑)
為何我這樣說?其實看我程式怎麼寫就知道
這是我在今天範例中跳轉到詳細視窗的程式片段
/**點擊後,跳轉至Shared Element*/ Intent intent = new Intent(MainActivity.this, SharedView.class); /**挾帶資料*/ intent.putExtra("Detail", imageId); /**設置Activity跳轉傳輸動畫*/ ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation( MainActivity.this, imageView, ViewCompat.getTransitionName(imageView)); startActivity(intent, options.toBundle());
其實就如同我說的,他不過就是一個跳頁的程式對吧?
那動畫怎麼來?主要就是這行啦
/**設置Activity跳轉傳輸動畫*/ ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation( MainActivity.this, imageView, ViewCompat.getTransitionName(imageView));
是吧?沒有想像中的難吧
那這篇文章就結束囉!謝謝各位!
看來你沒這麼容易被騙(笑)
好啦不要生氣(´・_・`)抱歉浪費你滾滑鼠的時間
那接下來就是實作囉
2. 架構介紹
如下圖
在開始前,可先按照我的架構把需要的檔案建好
至於建圖片的方法如下
drawable->右鍵->New->Vector Asset
然後選擇你喜歡的圖片,並決定大小就OK囉
3. 撰寫界面檔
接著是撰寫界面檔案,我先把全部給你後再來告訴你重點
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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" tools:context=".MainActivity"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerview" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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" tools:context=".SharedView"> <ImageView android:id="@+id/imageView_Detail" android:layout_width="0dp" android:layout_height="250dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@drawable/ic_launcher_background" android:transitionName="example_transition"/> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:text="這裡是第二個Activity" android:textAppearance="@style/TextAppearance.AppCompat.Large" android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/imageView_Detail" /> </androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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="wrap_content" android:layout_margin="5dp" android:background="?android:attr/selectableItemBackground" android:clickable="true" android:focusable="true" > <ImageView android:id="@+id/imageView_Image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:layout_marginBottom="8dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@drawable/ic_baseline_child_friendly_24" android:transitionName="example_transition" /> </androidx.constraintlayout.widget.ConstraintLayout>
嘿!別複製得太爽
注意到該注意的地方了嗎?
沒錯,這行( ゚Д゚)
android:transitionName="example_transition"
這行可以理解為做一個標記,將想要有動畫的元件套上去
然後開始的元件跟結束的元件都要有,這樣一來就完成動畫標記囉!
4. 潦草交代一下撰寫內容
對新手而言今天最難的部分反而是RecyclerView吧XD
真的不會的請移步!
☞碼農日常-『Android studio』基本RecyclerView用法
我直接先貼RecyclerView的Adapter!
class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> { int[] images; public OnImageClick onImageClick; /** * 使點擊到的資訊傳輸到Activity */ public void ItemClick(OnImageClick onImageClick) { this.onImageClick = onImageClick; } public RecyclerViewAdapter(int[] images) { this.images = images; } public class ViewHolder extends RecyclerView.ViewHolder { private ImageView imageView; public ViewHolder(@NonNull View itemView) { super(itemView); imageView = itemView.findViewById(R.id.imageView_Image); } } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) { holder.imageView.setImageDrawable(holder.itemView.getResources().getDrawable(images[position])); /**偵測點擊了item*/ holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onImageClick.onImageClick(images[position], holder.imageView); } }); } @Override public int getItemCount() { return images.length; } /** * 設置interface,使點擊到的item資料傳輸至外部Activity */ interface OnImageClick { void onImageClick(int imageId, ImageView imageView); } }
再來是MainActivity的部分
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /**設置圖片陣列*/ int[] images = {R.drawable.ic_baseline_drive_eta_24 , R.drawable.ic_baseline_computer_24 , R.drawable.ic_baseline_child_friendly_24}; /**設置Recyclerview*/ RecyclerView recyclerView = findViewById(R.id.recyclerview); RecyclerViewAdapter adapter = new RecyclerViewAdapter(images); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(adapter); /**取得點擊Recyclerview得到的內容*/ adapter.ItemClick(new RecyclerViewAdapter.OnImageClick() { @Override public void onImageClick(int imageId, ImageView imageView) { /**點擊後,跳轉至Shared Element*/ Intent intent = new Intent(MainActivity.this, SharedView.class); /**挾帶資料*/ intent.putExtra("Detail", imageId); /**設置Activity跳轉傳輸動畫*/ ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation( MainActivity.this, imageView, ViewCompat.getTransitionName(imageView)); startActivity(intent, options.toBundle()); } }); } }
這一段有沒有很熟悉呢?
/**點擊後,跳轉至Shared Element*/ Intent intent = new Intent(MainActivity.this, SharedView.class); /**挾帶資料*/ intent.putExtra("Detail", imageId); /**設置Activity跳轉傳輸動畫*/ ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation( MainActivity.this, imageView, ViewCompat.getTransitionName(imageView)); startActivity(intent, options.toBundle());
沒錯!就是一開始說的那一段
然後就剩接收端了
public class SharedView extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_shared_view); /**取得從上個Activity得到的id*/ int id = getIntent().getIntExtra("Detail",R.drawable.ic_launcher_background); /**將Intent得到的資源ID放進Shared的ImageView*/ ImageView imageView = findViewById(R.id.imageView_Detail); imageView.setImageDrawable(getDrawable(id)); } }
執行!
結語
OK,又是一篇簡單的功能完成了!
這個功能當時是親自被老闆要求的XD,後來隨便弄了弄後去交差(並沒有...)老闆也挺滿意(笑)
就如我一開始說的,寫這資料的人意外地並沒有很多,但是真不愧是我們台灣西邊的泱泱大國,隨便查都有相似的(只是未必每個人都寫得很好...)
那麼希望各位都能如實完成想要的功能喔!再會!
留言列表