Skip to content

Commit b9fd683

Browse files
authored
feat(android): flatten ListView layout (#14037)
* feat(android): flatten ListView layout * change layout order * adjust right padding * fix footer/headerView * update library, move to async updates
1 parent 3eda594 commit b9fd683

File tree

5 files changed

+113
-95
lines changed

5 files changed

+113
-95
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,91 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
3-
android:id="@+id/titanium_ui_listview_holder"
4-
android:layout_width="match_parent"
5-
android:layout_height="wrap_content"
6-
android:clipToPadding="false"
7-
android:outlineProvider="bounds">
2+
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:app="http://schemas.android.com/apk/res-auto"
4+
android:id="@+id/titanium_ui_listview_holder"
5+
android:layout_width="match_parent"
6+
android:layout_height="match_parent"
7+
android:clipToPadding="false"
8+
android:outlineProvider="bounds">
89

9-
<!-- Header Container -->
10-
<RelativeLayout
11-
android:id="@+id/titanium_ui_listview_holder_header_container"
12-
android:layout_width="match_parent"
13-
android:layout_height="wrap_content"
14-
android:layout_alignParentTop="true">
10+
<org.appcelerator.titanium.view.TiCompositeLayout
11+
android:id="@+id/titanium_ui_listview_holder_content"
12+
android:layout_width="wrap_content"
13+
android:layout_height="wrap_content"
14+
android:addStatesFromChildren="true"
15+
app:layout_constraintBottom_toTopOf="@+id/titanium_ui_listview_holder_footer_title"
16+
app:layout_constraintStart_toEndOf="@id/titanium_ui_listview_holder_left_image"
17+
app:layout_constraintTop_toBottomOf="@+id/titanium_ui_listview_holder_header_title" />
1518

16-
<org.appcelerator.titanium.view.TiCompositeLayout
17-
android:id="@+id/titanium_ui_listview_holder_header"
18-
android:layout_width="match_parent"
19-
android:layout_height="wrap_content"
20-
android:focusable="false"
21-
android:focusableInTouchMode="false"/>
22-
<TextView
23-
android:id="@+id/titanium_ui_listview_holder_header_title"
24-
android:layout_width="match_parent"
25-
android:layout_height="wrap_content"
26-
android:minHeight="18dp"
27-
android:paddingLeft="5dp"
28-
android:paddingRight="5dp"
29-
android:gravity="center_vertical"
30-
android:focusable="false"
31-
android:focusableInTouchMode="false"/>
32-
</RelativeLayout>
19+
<ImageView
20+
android:id="@+id/titanium_ui_listview_holder_left_image"
21+
android:layout_width="wrap_content"
22+
android:layout_height="wrap_content"
23+
android:focusable="false"
24+
android:focusableInTouchMode="false"
25+
android:paddingStart="6dp"
26+
android:paddingEnd="0dp"
27+
app:layout_constraintBottom_toTopOf="@id/titanium_ui_listview_holder_footer_title"
28+
app:layout_constraintStart_toStartOf="parent"
29+
app:layout_constraintTop_toBottomOf="@id/titanium_ui_listview_holder_header_title" />
3330

34-
<!-- Outer Content Container -->
35-
<RelativeLayout
36-
android:id="@+id/titanium_ui_listview_holder_outer_content_container"
37-
android:layout_width="match_parent"
38-
android:layout_height="wrap_content"
39-
android:layout_below="@id/titanium_ui_listview_holder_header_container"
40-
android:addStatesFromChildren="true">
31+
<ImageView
32+
android:id="@+id/titanium_ui_listview_holder_right_image"
33+
android:layout_width="wrap_content"
34+
android:layout_height="wrap_content"
35+
android:layout_marginEnd="6dp"
36+
android:focusable="false"
37+
android:focusableInTouchMode="false"
38+
app:layout_constraintBottom_toBottomOf="@id/titanium_ui_listview_holder_footer_title"
39+
app:layout_constraintEnd_toEndOf="parent"
40+
app:layout_constraintTop_toBottomOf="@id/titanium_ui_listview_holder_header_title" />
4141

42-
<ImageView
43-
android:id="@+id/titanium_ui_listview_holder_left_image"
44-
android:layout_width="wrap_content"
45-
android:layout_height="wrap_content"
46-
android:layout_alignParentLeft="true"
47-
android:layout_centerVertical="true"
48-
android:layout_marginLeft="6dp"
49-
android:focusable="false"
50-
android:focusableInTouchMode="false"/>
42+
<TextView
43+
android:id="@+id/titanium_ui_listview_holder_header_title"
44+
android:layout_width="0dp"
45+
android:layout_height="wrap_content"
46+
android:focusable="false"
47+
android:focusableInTouchMode="false"
48+
android:gravity="center_vertical"
49+
android:minHeight="18dp"
50+
android:paddingLeft="5dp"
51+
android:paddingRight="5dp"
52+
app:layout_constraintEnd_toEndOf="parent"
53+
app:layout_constraintStart_toStartOf="parent"
54+
app:layout_constraintTop_toTopOf="parent" />
5155

52-
<org.appcelerator.titanium.view.TiCompositeLayout
53-
android:id="@+id/titanium_ui_listview_holder_content"
54-
android:layout_width="match_parent"
55-
android:layout_height="wrap_content"
56-
android:layout_toRightOf="@id/titanium_ui_listview_holder_left_image"
57-
android:addStatesFromChildren="true"/>
56+
<TextView
57+
android:id="@+id/titanium_ui_listview_holder_footer_title"
58+
android:layout_width="0dp"
59+
android:layout_height="wrap_content"
60+
android:focusable="false"
61+
android:focusableInTouchMode="false"
62+
android:gravity="center_vertical"
63+
android:minHeight="18dp"
64+
android:paddingLeft="5dp"
65+
android:paddingRight="5dp"
66+
app:layout_constraintBottom_toBottomOf="parent"
67+
app:layout_constraintEnd_toEndOf="parent"
68+
app:layout_constraintStart_toStartOf="parent" />
5869

59-
<ImageView
60-
android:id="@+id/titanium_ui_listview_holder_right_image"
61-
android:layout_width="wrap_content"
62-
android:layout_height="wrap_content"
63-
android:layout_alignParentRight="true"
64-
android:layout_centerVertical="true"
65-
android:layout_marginRight="6dp"
66-
android:focusable="false"
67-
android:focusableInTouchMode="false"/>
6870

69-
</RelativeLayout>
71+
<org.appcelerator.titanium.view.TiCompositeLayout
72+
android:id="@+id/titanium_ui_listview_holder_header"
73+
android:layout_width="wrap_content"
74+
android:layout_height="wrap_content"
75+
android:focusable="false"
76+
android:focusableInTouchMode="false"
77+
app:layout_constraintEnd_toEndOf="parent"
78+
app:layout_constraintStart_toStartOf="parent"
79+
app:layout_constraintTop_toTopOf="parent" />
7080

71-
<!-- Footer Container -->
72-
<RelativeLayout
73-
android:id="@+id/titanium_ui_listview_holder_footer_container"
74-
android:layout_width="match_parent"
75-
android:layout_height="wrap_content"
76-
android:layout_alignParentBottom="true"
77-
android:layout_below="@id/titanium_ui_listview_holder_outer_content_container">
81+
<org.appcelerator.titanium.view.TiCompositeLayout
82+
android:id="@+id/titanium_ui_listview_holder_footer"
83+
android:layout_width="wrap_content"
84+
android:layout_height="wrap_content"
85+
android:focusable="false"
86+
android:focusableInTouchMode="false"
87+
app:layout_constraintBottom_toBottomOf="parent"
88+
app:layout_constraintEnd_toEndOf="parent"
89+
app:layout_constraintStart_toStartOf="parent" />
7890

79-
<org.appcelerator.titanium.view.TiCompositeLayout
80-
android:id="@+id/titanium_ui_listview_holder_footer"
81-
android:layout_width="match_parent"
82-
android:layout_height="wrap_content"
83-
android:focusable="false"
84-
android:focusableInTouchMode="false"/>
85-
<TextView
86-
android:id="@+id/titanium_ui_listview_holder_footer_title"
87-
android:layout_width="match_parent"
88-
android:layout_height="wrap_content"
89-
android:minHeight="18dp"
90-
android:paddingLeft="5dp"
91-
android:paddingRight="5dp"
92-
android:gravity="center_vertical"
93-
android:focusable="false"
94-
android:focusableInTouchMode="false" />
95-
</RelativeLayout>
96-
</RelativeLayout>
91+
</androidx.constraintlayout.widget.ConstraintLayout>

android/modules/ui/src/java/ti/modules/titanium/ui/widget/listview/ListViewAdapter.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616

1717
importandroid.content.Context;
1818
importandroid.view.ViewGroup;
19-
importandroid.widget.RelativeLayout;
2019

2120
importandroidx.annotation.NonNull;
21+
importandroidx.constraintlayout.widget.ConstraintLayout;
2222

2323
publicclassListViewAdapterextendsTiRecyclerViewAdapter<ListViewHolder, ListItemProxy>
2424
{
@@ -112,7 +112,7 @@ public void onBindViewHolder(@NonNull ListViewHolder holder, int position)
112112
publicListViewHolderonCreateViewHolder(@NonNullViewGroupparent, intviewType)
113113
{
114114
// Create new TableViewHolder instance.
115-
finalRelativeLayoutlayout = (RelativeLayout) inflater.inflate(id_holder, null);
115+
finalConstraintLayoutlayout = (ConstraintLayout) inflater.inflate(id_holder, null);
116116
returnnewListViewHolder(parent.getContext(), layout);
117117
}
118118

android/modules/ui/src/java/ti/modules/titanium/ui/widget/listview/ListViewHolder.java

+26-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
importorg.appcelerator.titanium.view.TiCompositeLayout;
1919
importorg.appcelerator.titanium.view.TiUIView;
2020

21+
importandroid.annotation.SuppressLint;
2122
importandroid.app.Activity;
2223
importandroid.content.Context;
2324
importandroid.content.res.Resources;
@@ -33,6 +34,8 @@
3334
importandroid.widget.ImageView;
3435
importandroid.widget.TextView;
3536

37+
importandroidx.constraintlayout.widget.ConstraintLayout;
38+
importandroidx.constraintlayout.widget.ConstraintSet;
3639
importandroidx.recyclerview.widget.RecyclerView;
3740

3841
importjava.lang.ref.WeakReference;
@@ -70,7 +73,7 @@ public ListViewHolder(final Context context, final ViewGroup viewGroup)
7073
// Header attributes.
7174
setTitleAttributes("header", context, this.headerTitle);
7275

73-
this.container = viewGroup.findViewById(R.id.titanium_ui_listview_holder_outer_content_container);
76+
this.container = viewGroup.findViewById(R.id.titanium_ui_listview_holder);
7477

7578
this.leftImage = viewGroup.findViewById(R.id.titanium_ui_listview_holder_left_image);
7679

@@ -92,6 +95,7 @@ public ListViewHolder(final Context context, final ViewGroup viewGroup)
9295
* @param proxy ListItemProxy to bind.
9396
* @param selected Is row selected.
9497
*/
98+
@SuppressLint("ClickableViewAccessibility")
9599
publicvoidbind(finalListItemProxyproxy, finalbooleanselected)
96100
{
97101
reset();
@@ -165,7 +169,6 @@ public void bind(final ListItemProxy proxy, final boolean selected)
165169
this.rightImage.setVisibility(View.VISIBLE);
166170

167171
RecyclerView.ViewHoldermViewHolder = this;
168-
169172
this.rightImage.setOnTouchListener(newView.OnTouchListener()
170173
{
171174
@Override
@@ -252,7 +255,7 @@ public boolean onTouch(View view, MotionEvent motionEvent)
252255
borderView.setAddStatesFromChildren(true);
253256

254257
// Amend maximum size for content to parent ListView measured height.
255-
this.content.setChildFillHeight(nativeListView.getMeasuredHeight());
258+
this.container.setMinimumHeight(nativeListView.getMeasuredHeight());
256259

257260
// Add ListViewItem to content.
258261
this.content.addView(borderView, view.getLayoutParams());
@@ -362,6 +365,16 @@ private void setHeaderFooter(TiViewProxy listViewProxy,
362365

363366
this.header.addView(headerView, view.getLayoutParams());
364367
this.header.setVisibility(View.VISIBLE);
368+
369+
ConstraintSetconstraintSet = newConstraintSet();
370+
constraintSet.clone((ConstraintLayout) this.container);
371+
constraintSet.connect(R.id.titanium_ui_listview_holder_content, ConstraintSet.TOP,
372+
R.id.titanium_ui_listview_holder_header, ConstraintSet.BOTTOM, 0);
373+
constraintSet.connect(R.id.titanium_ui_listview_holder_left_image, ConstraintSet.TOP,
374+
R.id.titanium_ui_listview_holder_header, ConstraintSet.BOTTOM, 0);
375+
constraintSet.connect(R.id.titanium_ui_listview_holder_right_image, ConstraintSet.TOP,
376+
R.id.titanium_ui_listview_holder_header, ConstraintSet.BOTTOM, 0);
377+
constraintSet.applyTo((ConstraintLayout) this.container);
365378
}
366379
}
367380
}
@@ -396,6 +409,16 @@ private void setHeaderFooter(TiViewProxy listViewProxy,
396409

397410
this.footer.addView(footerView, view.getLayoutParams());
398411
this.footer.setVisibility(View.VISIBLE);
412+
413+
ConstraintSetconstraintSet = newConstraintSet();
414+
constraintSet.clone((ConstraintLayout) this.container);
415+
constraintSet.connect(R.id.titanium_ui_listview_holder_content, ConstraintSet.BOTTOM,
416+
R.id.titanium_ui_listview_holder_footer, ConstraintSet.TOP, 0);
417+
constraintSet.connect(R.id.titanium_ui_listview_holder_left_image, ConstraintSet.BOTTOM,
418+
R.id.titanium_ui_listview_holder_footer, ConstraintSet.TOP, 0);
419+
constraintSet.connect(R.id.titanium_ui_listview_holder_right_image, ConstraintSet.BOTTOM,
420+
R.id.titanium_ui_listview_holder_footer, ConstraintSet.TOP, 0);
421+
constraintSet.applyTo((ConstraintLayout) this.container);
399422
}
400423
}
401424
}

android/modules/ui/src/java/ti/modules/titanium/ui/widget/listview/TiRecyclerViewAdapter.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public void update(List<V> newModels, boolean force)
117117
return;
118118
}
119119

120-
finalvardiffResult = DiffUtil.calculateDiff(newDiffCallback(newModelsClone, this.models));
120+
finalvardiffResult = DiffUtil.calculateDiff(newAsyncListDiffer(newModelsClone, this.models));
121121

122122
// Update models.
123123
this.models = newModelsClone;
@@ -129,13 +129,13 @@ public void update(List<V> newModels, boolean force)
129129
/**
130130
* Define DiffUtil.Callback to optimize updating the adapter.
131131
*/
132-
privateclassDiffCallbackextendsDiffUtil.Callback
132+
privateclassAsyncListDifferextendsDiffUtil.Callback
133133
{
134134

135135
List<V> newViews;
136136
List<V> oldViews;
137137

138-
publicDiffCallback(List<V> newViews, List<V> oldViews)
138+
publicAsyncListDiffer(List<V> newViews, List<V> oldViews)
139139
{
140140
this.newViews = newViews;
141141
this.oldViews = oldViews;

android/titanium/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ dependencies {
254254
implementation 'androidx.exifinterface:exifinterface:1.3.6'
255255
implementation "androidx.fragment:fragment:${project.ext.tiAndroidXFragmentLibVersion}"
256256
implementation 'androidx.media:media:1.6.0'
257-
implementation 'androidx.recyclerview:recyclerview:1.3.1'
257+
implementation 'androidx.recyclerview:recyclerview:1.3.2'
258258
implementation 'androidx.recyclerview:recyclerview-selection:1.1.0'
259259
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
260260
implementation 'androidx.transition:transition:1.4.1'

0 commit comments

Comments
 (0)
close