Grid表示
前に
画像とテキストを設定したRecyclerViewのコード
を元にして作成してきます
データセットは要素を削除したり可変長となるのでArrayListで作ります
RecyclerViewでは実はListViewのように縦方向のスクロールをデフォルトで設定しているのですが、それを変更することでGridになります
具体的には、LinearLayoutManagerからGridLayoutManagerに変更
また上下方向と左右方向へのスクロールの変更もできます
GridLayoutManager (
Context context,
int spanCount, // The number of columns or rows in the grid.
int orientation, // HORIZONTAL or VERTICAL.
boolean reverseLayout // When set to true, layouts from end to start
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation "androidx.cardview:cardview:1.0.0"
onMove()はGridなので上下だけでなく左右も動けるように
UP, DOWN, LEFt, RIGHTを可動域とします
ここでスワイプと重なるので左右で削除か移動か分かりにくくなる可能性はあります
実際は長押しで移動ですが、削除はスワイプではなくChipなどで分かりやすくした方がいいかもしれません
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(
new ItemTouchHelper.SimpleCallback(
// onMove
ItemTouchHelper.UP | ItemTouchHelper.DOWN |
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT,
// onSwipe
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
@Override
public boolean onMove(
@Override
public void onSwiped(
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ItemTouchHelper
itemTouchHelper
=
new
ItemTouchHelper
(
new
ItemTouchHelper
.
SimpleCallback
(
// onMove
ItemTouchHelper
.
UP
|
ItemTouchHelper
.
DOWN
|
ItemTouchHelper
.
LEFT
|
ItemTouchHelper
.
RIGHT
,
// onSwipe
ItemTouchHelper
.
LEFT
|
ItemTouchHelper
.
RIGHT
)
{
@Override
public
boolean
onMove
(
.
.
.
}
@Override
public
void
onSwiped
(
.
.
.
}
}
)
;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.GridLayoutManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private static final String[] names = {
"Bellflower", "Bougainvillea", "Cosmos", "Cosmos field",
"Delphinium", "Flowers", "Lotus", "Spring Flowers"
// それぞれの画像ファイルをdarawableに入れます
// ArrayListにコピーするためintからInteger型にしました
private static final Integer[] photos = {
R.drawable.bellflower, R.drawable.bougainvillea,
R.drawable.cosmos, R.drawable.cosmos_field,
R.drawable.delphinium, R.drawable.flowers,
R.drawable.lotus, R.drawable.spring_flowers
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = findViewById(R.id.my_recycler_view);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
recyclerView.setHasFixedSize(true);
// use a linear layout manager
recyclerView.setLayoutManager(
new GridLayoutManager(this, 2, RecyclerView.VERTICAL, false));
// 配列をArrayListにコピー
List<String> itemNames = new ArrayList<>(Arrays.asList(names));
List<Integer> itemImages = new ArrayList<>(Arrays.asList(photos));
// specify an adapter (see also next example)
MyAdapter adapter = new MyAdapter(itemImages, itemNames);
recyclerView.setAdapter(adapter);
RecyclerView.ItemDecoration itemDecoration =
new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
recyclerView.addItemDecoration(itemDecoration);
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(
new ItemTouchHelper.SimpleCallback(
ItemTouchHelper.UP | ItemTouchHelper.DOWN |
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT,
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT
@Override
public boolean onMove(@NonNull RecyclerView recyclerView,
@NonNull RecyclerView.ViewHolder viewHolder,
@NonNull RecyclerView.ViewHolder target) {
final int fromPos = viewHolder.getAbsoluteAdapterPosition();
final int toPos = target.getAbsoluteAdapterPosition();
adapter.notifyItemMoved(fromPos, toPos);
return true;
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
itemImages.remove(viewHolder.getAbsoluteAdapterPosition());
itemNames.remove(viewHolder.getAbsoluteAdapterPosition());
adapter.notifyItemRemoved(viewHolder.getAbsoluteAdapterPosition());
itemTouchHelper.attachToRecyclerView(recyclerView);
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
//package your.package.name;
import
androidx
.
annotation
.
NonNull
;
import
androidx
.
appcompat
.
app
.
AppCompatActivity
;
import
android
.
os
.
Bundle
;
import
androidx
.
recyclerview
.
widget
.
DividerItemDecoration
;
import
androidx
.
recyclerview
.
widget
.
RecyclerView
;
import
androidx
.
recyclerview
.
widget
.
ItemTouchHelper
;
import
androidx
.
recyclerview
.
widget
.
GridLayoutManager
;
import
java
.
util
.
ArrayList
;
import
java
.
util
.
Arrays
;
import
java
.
util
.
List
;
public
class
MainActivity
extends
AppCompatActivity
{
private
static
final
String
[
]
names
=
{
"Bellflower"
,
"Bougainvillea"
,
"Cosmos"
,
"Cosmos field"
,
"Delphinium"
,
"Flowers"
,
"Lotus"
,
"Spring Flowers"
}
;
// それぞれの画像ファイルをdarawableに入れます
// ArrayListにコピーするためintからInteger型にしました
private
static
final
Integer
[
]
photos
=
{
R
.
drawable
.
bellflower
,
R
.
drawable
.
bougainvillea
,
R
.
drawable
.
cosmos
,
R
.
drawable
.
cosmos_field
,
R
.
drawable
.
delphinium
,
R
.
drawable
.
flowers
,
R
.
drawable
.
lotus
,
R
.
drawable
.
spring
_
flowers
}
;
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
)
;
setContentView
(
R
.
layout
.
activity_main
)
;
RecyclerView
recyclerView
=
findViewById
(
R
.
id
.
my_recycler_view
)
;
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
recyclerView
.
setHasFixedSize
(
true
)
;
// use a linear layout manager
recyclerView
.
setLayoutManager
(
new
GridLayoutManager
(
this
,
2
,
RecyclerView
.
VERTICAL
,
false
)
)
;
// 配列をArrayListにコピー
List
<String>
itemNames
=
new
ArrayList
<>
(
Arrays
.
asList
(
names
)
)
;
List
<Integer>
itemImages
=
new
ArrayList
<>
(
Arrays
.
asList
(
photos
)
)
;
// specify an adapter (see also next example)
MyAdapter
adapter
=
new
MyAdapter
(
itemImages
,
itemNames
)
;
recyclerView
.
setAdapter
(
adapter
)
;
RecyclerView
.
ItemDecoration
itemDecoration
=
new
DividerItemDecoration
(
this
,
DividerItemDecoration
.
VERTICAL
)
;
recyclerView
.
addItemDecoration
(
itemDecoration
)
;
ItemTouchHelper
itemTouchHelper
=
new
ItemTouchHelper
(
new
ItemTouchHelper
.
SimpleCallback
(
ItemTouchHelper
.
UP
|
ItemTouchHelper
.
DOWN
|
ItemTouchHelper
.
LEFT
|
ItemTouchHelper
.
RIGHT
,
ItemTouchHelper
.
LEFT
|
ItemTouchHelper
.
RIGHT
)
{
@Override
public
boolean
onMove
(
@NonNull
RecyclerView
recyclerView
,
@NonNull
RecyclerView
.
ViewHolder
viewHolder
,
@NonNull
RecyclerView
.
ViewHolder
target
)
{
final
int
fromPos
=
viewHolder
.
getAbsoluteAdapterPosition
(
)
;
final
int
toPos
=
target
.
getAbsoluteAdapterPosition
(
)
;
adapter
.
notifyItemMoved
(
fromPos
,
toPos
)
;
return
true
;
}
@Override
public
void
onSwiped
(
@NonNull
RecyclerView
.
ViewHolder
viewHolder
,
int
direction
)
{
itemImages
.
remove
(
viewHolder
.
getAbsoluteAdapterPosition
(
)
)
;
itemNames
.
remove
(
viewHolder
.
getAbsoluteAdapterPosition
(
)
)
;
adapter
.
notifyItemRemoved
(
viewHolder
.
getAbsoluteAdapterPosition
(
)
)
;
}
}
)
;
itemTouchHelper
.
attachToRecyclerView
(
recyclerView
)
;
}
}
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private final List<Integer> iImages;
private final List<String> iNames;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
static class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
ImageView imageView;
TextView textView;
ViewHolder(View v) {
super(v);
imageView = v.findViewById(R.id.image_view);
textView = v.findViewById(R.id.text_view);
// Provide a suitable constructor (depends on the kind of dataset)
MyAdapter(List<Integer> itemImages, List<String> itemNames) {
this.iImages = itemImages;
this.iNames = itemNames;
// Create new views (invoked by the layout manager)
@Override
@NonNull
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// create a new view
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.grid_view, parent, false);
// set the view's size, margins, paddings and layout parameters
return new ViewHolder(view);
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
holder.imageView.setImageResource(iImages.get(position));
holder.textView.setText(iNames.get(position));
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return iNames.size();
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
//package your.package.name;
import
androidx
.
annotation
.
NonNull
;
import
androidx
.
recyclerview
.
widget
.
RecyclerView
;
import
android
.
view
.
LayoutInflater
;
import
android
.
view
.
View
;
import
android
.
view
.
ViewGroup
;
import
android
.
widget
.
ImageView
;
import
android
.
widget
.
TextView
;
import
java
.
util
.
List
;
public
class
MyAdapter
extends
RecyclerView
.
Adapter
<
MyAdapter
.
ViewHolder
>
{
private
final
List
<Integer>
iImages
;
private
final
List
<String>
iNames
;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
static
class
ViewHolder
extends
RecyclerView
.
ViewHolder
{
// each data item is just a string in this case
ImageView
imageView
;
TextView
textView
;
ViewHolder
(
View
v
)
{
super
(
v
)
;
imageView
=
v
.
findViewById
(
R
.
id
.
image_view
)
;
textView
=
v
.
findViewById
(
R
.
id
.
text_view
)
;
}
}
// Provide a suitable constructor (depends on the kind of dataset)
MyAdapter
(
List
<Integer>
itemImages
,
List
<String>
itemNames
)
{
this
.
iImages
=
itemImages
;
this
.
iNames
=
itemNames
;
}
// Create new views (invoked by the layout manager)
@Override
@NonNull
public
ViewHolder
onCreateViewHolder
(
@NonNull
ViewGroup
parent
,
int
viewType
)
{
// create a new view
View
view
=
LayoutInflater
.
from
(
parent
.
getContext
(
)
)
.
inflate
(
R
.
layout
.
grid_view
,
parent
,
false
)
;
// set the view's size, margins, paddings and layout parameters
return
new
ViewHolder
(
view
)
;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public
void
onBindViewHolder
(
@NonNull
ViewHolder
holder
,
int
position
)
{
// - get element from your dataset at this position
// - replace the contents of the view with that element
holder
.
imageView
.
setImageResource
(
iImages
.
get
(
position
)
)
;
holder
.
textView
.
setText
(
iNames
.
get
(
position
)
)
;
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public
int
getItemCount
(
)
{
return
iNames
.
size
(
)
;
}
}
<?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">
<!-- A RecyclerView with some commonly used attributes -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?
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"
>
<
!
--
A
RecyclerView
with
some
commonly
used
attributes
--
>
<
androidx
.
recyclerview
.
widget
.
RecyclerView
android
:
id
=
"@+id/my_recycler_view"
android
:
scrollbars
=
"vertical"
android
:
layout_width
=
"match_parent"
android
:
layout_height
=
"match_parent"
app
:
layout_constraintBottom_toBottomOf
=
"parent"
app
:
layout_constraintLeft_toLeftOf
=
"parent"
app
:
layout_constraintRight_toRightOf
=
"parent"
app
:
layout_constraintTop_toTopOf
=
"parent"
/
>
<
/
androidx
.
constraintlayout
.
widget
.
ConstraintLayout
>
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
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"
app:cardCornerRadius="10dp"
app:cardElevation="5dp"
app:contentPadding="10dp"
app:cardUseCompatPadding="true">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/image_view"
android:layout_width="wrap_content"
android:layout_height="160dp"
android:contentDescription="@string/description" />
<TextView
android:id="@+id/text_view"
android:textSize="18sp"
android:textColor="@android:color/black"
android:textAlignment="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
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
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
androidx
.
cardview
.
widget
.
CardView
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"
app
:
cardCornerRadius
=
"10dp"
app
:
cardElevation
=
"5dp"
app
:
contentPadding
=
"10dp"
app
:
cardUseCompatPadding
=
"true"
>
<
LinearLayout
android
:
orientation
=
"vertical"
android
:
layout_width
=
"match_parent"
android
:
layout_height
=
"wrap_content"
tools
:
ignore
=
"UseCompoundDrawables"
>
<
ImageView
android
:
id
=
"@+id/image_view"
android
:
layout_width
=
"wrap_content"
android
:
layout_height
=
"160dp"
android
:
contentDescription
=
"@string/description"
/
>
<
TextView
android
:
id
=
"@+id/text_view"
android
:
textSize
=
"18sp"
android
:
textColor
=
"@android:color/black"
android
:
textAlignment
=
"center"
android
:
layout_width
=
"match_parent"
android
:
layout_height
=
"wrap_content"
/
>
<
/
LinearLayout
>
<
/
androidx
.
cardview
.
widget
.
CardView
>
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation "androidx.cardview:cardview:1.0.0"
<resources>
<string name="app_name">Your App Name</string>
<string name="description">picture</string>
</resources>