初心者です。
AndroidStudioでMaterial3なカルーセルを作りたああああああああああああああい!!
ということで作っていきます。
完成した物
https://github.com/SousiOmine/Material3_Carousel_demo
参考にした資料
https://www.youtube.com/watch?v=nV48OJQvvIc
Atriiという方の解説動画です
https://github.com/material-components/material-components-android/blob/master/docs/components/Carousel.md
公式ドキュメントです
コピペで作っていく
Material_Carouselという名前で新規プロジェクトを作成しました。
試しにビルドしようとするとエラー発生!
何もしていないのに壊れた!
An issue was found when checking AAR metadata:
1. Dependency 'androidx.activity:activity:1.8.0' requires libraries and applications that
depend on it to compile against version 34 or later of the
Android APIs.
:app is currently compiled against android-33.
Also, the maximum recommended compile SDK version for Android Gradle
plugin 7.4.2 is 33.
Recommended action: Update this project's version of the Android Gradle
plugin to one that supports 34, then update this project to use
compileSdkVerion of at least 34.
Note that updating a library or application's compileSdkVersion (which
allows newer APIs to be used) can be done separately from updating
targetSdkVersion (which opts the app in to new runtime behavior) and
minSdkVersion (which determines which devices the app can be installed
on).
なんでテンプレのままなのに動かないんだよ〇〇〇!
Gradleのバージョンを上げてcomplineSdkVersionを上げろと書いてありますがGradleは後回しにしても多分動くので
build.gradle(app)を
android {
namespace 'com.example.material_carousel'
//compileSdk 33
compileSdk 34
defaultConfig {
applicationId "com.example.material_carousel"
minSdk 24
//targetSdk 33
targetSdk 34
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
のように変えると正常に動作しました。
カルーセルまだ全く触れてませんごめんね
Material3のライブラリを使えるようにgradleに追記します
dependencies {
implementation 'com.google.android.material:material:1.11.0'
}
res/layoutにカルーセルに表示させる内容を定義する?xmlを書きます。というよりは公式ドキュメントからコピペします。
私は画像と概要みたいなのを出したいのでテキストも出します
画像にはとりあえres\drawableに適当な画像を置いて指定しておきました
<com.google.android.material.carousel.MaskableFrameLayout
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:id="@+id/carousel_item_container"
android:layout_width="150dp"
android:layout_height="match_parent"
android:layout_marginStart="4dp"
android:layout_marginEnd="4dp"
android:foreground="?attr/selectableItemBackground"
app:shapeAppearance="?attr/shapeAppearanceCornerExtraLarge">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/carousel_image_view"
android:src="@drawable/karen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"/>
<TextView
android:id="@+id/carousel_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:textSize="32sp"
android:textColor="@color/white"
android:text="Karen"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.carousel.MaskableFrameLayout>
activity_main.xmlにRecyclerViewを置きます。このときにlayoutManagerにmaterialライブラリのCarouselLayoutManagerを指定するらしい
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/carousel_recycler_view"
app:layoutManager="com.google.android.material.carousel.CarouselLayoutManager"
tools:listitem="@layout/carousel_layout"
android:layout_width="match_parent"
android:layout_height="196dp"
android:clipChildren="false"
android:clipToPadding="false"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
ちなみにRecyclerViewから書き始めるとlistitemがないのでプレビューが出ず怖くなります
これでactivity_main.xmlのデザインプレビューを見ると
ぽい!ぽいぞ!
ただ今はビルドして動かしてもなにも表示されません
E/RecyclerView: No adapter attached; skipping layout とかぬかすので、adapterとやらを作ります
参考にした資料の動画ではkotlinで書いててなにしてるのか全く分からなかったので、過去に自分で書いたJavaプログラムを見て思い出しながら書きました
まずカルーセルに表示するデータを格納するクラスを作ります。画像と文字を格納できればいいです
package com.example.material_carousel;
import android.graphics.Bitmap;
public class CarouselModel {
public Bitmap image;
public String text;
public CarouselModel(Bitmap img, String txt) {
this.image = img;
this.text = txt;
}
}
次にViewHolderというわけわからんクラスも作ります。多分Adapterとカルーセルを結びつけるようなことをしています
package com.example.material_carousel;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class CarouselHolder extends RecyclerView.ViewHolder{
public ImageView imageView;
public TextView textView;
public CarouselHolder(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.carousel_image_view);
textView = itemView.findViewById(R.id.carousel_text_view);
}
}
そしてAdapterを作ります。なんかいろいろするやつです
package com.example.material_carousel;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class CarouselAdapter extends RecyclerView.Adapter<CarouselHolder> {
ArrayList<CarouselModel> models;
MainActivity main_activity;
public CarouselAdapter(ArrayList<CarouselModel> list, MainActivity ma)
{
this.models = list;
this.main_activity = ma;
}
@NonNull
@Override
public CarouselHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//なにかよくわかっていない
View inflate = LayoutInflater.from(parent.getContext()).inflate(R.layout.carousel_layout, parent, false);
CarouselHolder carouselHolder = new CarouselHolder(inflate);
return carouselHolder;
}
@Override
public void onBindViewHolder(@NonNull CarouselHolder holder, int position) {
//各項目に必要な要素をセットする
holder.imageView.setImageBitmap(models.get(position).image);
holder.textView.setText(models.get(position).text);
holder.imageView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
tapFunc();
}
});
}
private void tapFunc() //要素が押されたときに実行するやつをここに書く
{
Toast.makeText(main_activity, "九条カレン", Toast.LENGTH_SHORT).show();
}
@Override
public int getItemCount() {
return models.size();
}
}
で、最後にアダプターをコードで指定してやります
今回はMainActivityにカルーセルを出す想定なのでMainActivityに書いていきます
package com.example.material_carousel;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
ArrayList<CarouselModel> models;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
models = new ArrayList<>();
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.karen);
//使った画像がでかすぎて何もしないとエラーを吐くので小さくしてます
bmp = Bitmap.createScaledBitmap(bmp, 500, 500, false);
models.add(new CarouselModel(bmp, "Karen1"));
models.add(new CarouselModel(bmp, "Karen2"));
models.add(new CarouselModel(bmp, "Karen3"));
models.add(new CarouselModel(bmp, "Karen4"));
models.add(new CarouselModel(bmp, "Karen5"));
RecyclerView recyclerView = findViewById(R.id.carousel_recycler_view);
//アダプターを指定
recyclerView.setAdapter(new CarouselAdapter(models, this));
}
}
ここまでいけばもう動くはず!
これは一体、どうなっちゃうんだ~~!?!?
うごいたあああああああああああ!
でもなんか...ダサくない?
テーマを変えるのを忘れていました
<style name="Theme.Material_Carousel" parent="Theme.Material3.Light">
以下略
あとRecyclerViewにpadding(隙間)を設定しました
おおお!Material3になりました!マテリアル3だせえええええ~
いかがでしたか?
ここまで作ったやつはGitHubに上げました
https://github.com/SousiOmine/Material3_Carousel_demo
というわけでカレンちゃんを眺められる世界最高のアプリが完成したのでここで終わります
誰かの参考になれば幸いです