Skip to content

Commit 995d878

Browse files
committed
improved encoded codes screen
1 parent 82e1e76 commit 995d878

File tree

8 files changed

+152
-81
lines changed

8 files changed

+152
-81
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
# Changelog
22
All notable changes to this project will be documented in this file.
33

4+
## [0.14.7]
5+
6+
### Changes
7+
- Added support for encodedCodes 'maxChars' property
8+
- Layout and Behaviour improvements to the encodedCodes screen
9+
- Renamed key Snabble.Receipt.noReceipt to Snabble.Receipts.noReceipt
10+
11+
### New String Keys
12+
- Snabble.QRCode.entry.title
13+
- Snabble.Receipts.noReceipt
14+
415
## [0.14.6]
516

617
### Fixed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ allprojects {
2323
}
2424

2525
project.ext {
26-
sdkVersion='0.14.6'
26+
sdkVersion='0.14.7'
2727
versionCode=1
2828

2929
compileSdkVersion=28

ui/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ dependencies {
3939
implementation project(':utils')
4040
implementation project(':core')
4141

42-
implementation 'androidx.core:core:1.0.1'
42+
implementation 'androidx.core:core:1.0.2'
4343
implementation 'androidx.appcompat:appcompat:1.0.2'
4444
implementation 'androidx.recyclerview:recyclerview:1.0.0'
4545
implementation 'androidx.cardview:cardview:1.0.0'

ui/src/main/java/io/snabble/sdk/ui/checkout/CheckoutEncodedCodesView.java

Lines changed: 105 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@
55
import android.os.Looper;
66
import androidx.annotation.NonNull;
77
import android.util.DisplayMetrics;
8-
import android.view.Gravity;
98
import android.view.View;
109
import android.view.ViewGroup;
1110
import android.widget.Button;
1211
import android.widget.FrameLayout;
12+
import android.widget.LinearLayout;
1313
import android.widget.TextView;
1414

1515
import java.util.ArrayList;
1616

1717
import androidx.recyclerview.widget.LinearLayoutManager;
18+
import androidx.recyclerview.widget.LinearSmoothScroller;
1819
import androidx.recyclerview.widget.RecyclerView;
1920
import io.snabble.sdk.Checkout;
2021
import io.snabble.sdk.Project;
@@ -23,19 +24,20 @@
2324
import io.snabble.sdk.encodedcodes.EncodedCodesOptions;
2425
import io.snabble.sdk.ui.R;
2526
import io.snabble.sdk.ui.SnabbleUI;
26-
import io.snabble.sdk.ui.SnabbleUICallback;
2727
import io.snabble.sdk.BarcodeFormat;
28+
import io.snabble.sdk.ui.SnabbleUICallback;
2829
import io.snabble.sdk.ui.scanner.BarcodeView;
2930
import io.snabble.sdk.ui.telemetry.Telemetry;
3031
import io.snabble.sdk.ui.utils.OneShotClickListener;
3132

3233
class CheckoutEncodedCodesView extends FrameLayout implements View.OnLayoutChangeListener {
3334
private FrameLayout scrollContainer;
34-
private TextView explanationText;
3535
private TextView explanationText2;
3636
private Project project;
3737
private EncodedCodesGenerator encodedCodesGenerator;
38+
private CodeListView codeListView;
3839
private int maxSizeMm;
40+
private Button paidButton;
3941

4042
public CheckoutEncodedCodesView(Context context) {
4143
super(context);
@@ -56,38 +58,38 @@ private void inflateView(EncodedCodesOptions options) {
5658

5759
scrollContainer = findViewById(R.id.scroll_container);
5860

59-
explanationText = findViewById(R.id.explanation1);
6061
explanationText2 = findViewById(R.id.explanation2);
6162

6263
maxSizeMm = options.maxSizeMm;
6364
encodedCodesGenerator = new EncodedCodesGenerator(options);
6465

65-
final Button paidButton = findViewById(R.id.paid);
66-
67-
paidButton.setVisibility(View.INVISIBLE);
68-
paidButton.setAlpha(0);
69-
Handler handler = new Handler(Looper.getMainLooper());
70-
handler.postDelayed(new Runnable() {
71-
@Override
72-
public void run() {
73-
paidButton.setVisibility(View.VISIBLE);
74-
paidButton.animate().setDuration(150).alpha(1).start();
75-
paidButton.setEnabled(true);
76-
}
77-
}, 5000);
78-
66+
paidButton = findViewById(R.id.paid);
7967
paidButton.setOnClickListener(new OneShotClickListener() {
8068
@Override
8169
public void click() {
82-
Project project = SnabbleUI.getProject();
83-
project.getCheckout().approveOfflineMethod();
70+
if (isAtLastBarcode()) {
71+
Project project = SnabbleUI.getProject();
72+
project.getCheckout().approveOfflineMethod();
8473

85-
SnabbleUICallback uiCallback = SnabbleUI.getUiCallback();
86-
if (uiCallback != null) {
87-
uiCallback.goBack();
88-
}
74+
SnabbleUICallback uiCallback = SnabbleUI.getUiCallback();
75+
if (uiCallback != null) {
76+
uiCallback.goBack();
77+
}
8978

90-
Telemetry.event(Telemetry.Event.CheckoutFinishByUser);
79+
Telemetry.event(Telemetry.Event.CheckoutFinishByUser);
80+
} else {
81+
final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) codeListView.getLayoutManager();
82+
RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(getContext()) {
83+
@Override
84+
protected int getVerticalSnapPreference() {
85+
return SNAP_TO_START;
86+
}
87+
};
88+
89+
int scrollTo = getNextBarcodeIndex();
90+
smoothScroller.setTargetPosition(scrollTo);
91+
linearLayoutManager.startSmoothScroll(smoothScroller);
92+
}
9193
}
9294
});
9395

@@ -106,20 +108,22 @@ public void click() {
106108
}
107109
}
108110

109-
private void updateExplanationText(int codeCount) {
110-
int resId;
111-
if (codeCount > 1) {
112-
resId = R.string.Snabble_QRCode_showTheseCodes;
113-
} else {
114-
resId = R.string.Snabble_QRCode_showThisCode;
111+
public int getNextBarcodeIndex() {
112+
final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) codeListView.getLayoutManager();
113+
if (linearLayoutManager != null) {
114+
return linearLayoutManager.findLastVisibleItemPosition();
115115
}
116116

117-
if (SnabbleUI.getActionBar() != null) {
118-
explanationText.setVisibility(View.GONE);
119-
SnabbleUI.getActionBar().setTitle(resId);
120-
} else {
121-
explanationText.setText(resId);
117+
return 0;
118+
}
119+
120+
public boolean isAtLastBarcode() {
121+
final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) codeListView.getLayoutManager();
122+
if (linearLayoutManager != null) {
123+
return linearLayoutManager.findLastCompletelyVisibleItemPosition() == linearLayoutManager.getItemCount() - 1;
122124
}
125+
126+
return true;
123127
}
124128

125129
@Override
@@ -146,19 +150,37 @@ public void onLayoutChange(View v, int left, int top, int right, int bottom,
146150
handler.post(new Runnable() {
147151
@Override
148152
public void run() {
153+
DisplayMetrics dm = getResources().getDisplayMetrics();
154+
149155
if (scrollContainer.getWidth() > 0 && scrollContainer.getHeight() > 0) {
150156
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
151157
ViewGroup.LayoutParams.MATCH_PARENT,
152-
ViewGroup.LayoutParams.WRAP_CONTENT);
153-
lp.gravity = Gravity.CENTER;
158+
ViewGroup.LayoutParams.MATCH_PARENT);
159+
154160
scrollContainer.removeAllViews();
155-
scrollContainer.addView(new CodeListView(getContext()), lp);
161+
codeListView = new CodeListView(getContext());
162+
scrollContainer.addView(codeListView, lp);
163+
codeListView.addOnScrollListener(new RecyclerView.OnScrollListener() {
164+
@Override
165+
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
166+
super.onScrolled(recyclerView, dx, dy);
167+
168+
CodeListViewAdapter adapter = ((CodeListViewAdapter)codeListView.getAdapter());
169+
if (isAtLastBarcode()) {
170+
paidButton.setText(R.string.Snabble_QRCode_didPay);
171+
} else {
172+
paidButton.setText(getResources().getString(R.string.Snabble_QRCode_nextCode,
173+
getNextBarcodeIndex() + 1, adapter.getItemCount()));
174+
}
175+
}
176+
});
177+
178+
codeListView.setPadding(0, (int) (12 * dm.density), 0, 0);
179+
codeListView.setOverScrollMode(View.OVER_SCROLL_NEVER);
156180
}
157181

158-
DisplayMetrics dm = getResources().getDisplayMetrics();
159182
int dpHeight = Math.round(scrollContainer.getHeight() / dm.density);
160183
if (dpHeight < 220) {
161-
explanationText.setVisibility(View.GONE);
162184
explanationText2.setVisibility(View.GONE);
163185
}
164186
}
@@ -176,12 +198,18 @@ public CodeListView(@NonNull Context context) {
176198
}
177199

178200
private class ViewHolder extends RecyclerView.ViewHolder {
201+
BarcodeView barcodeView;
202+
TextView title;
203+
179204
ViewHolder(@NonNull View itemView) {
180205
super(itemView);
206+
207+
barcodeView = itemView.findViewById(R.id.barcode);
208+
title = itemView.findViewById(R.id.title);
181209
}
182210
}
183211

184-
private class CodeListViewAdapter extends RecyclerView.Adapter {
212+
private class CodeListViewAdapter extends RecyclerView.Adapter<ViewHolder> {
185213
private ArrayList<String> codes;
186214

187215
CodeListViewAdapter() {
@@ -193,41 +221,61 @@ private class CodeListViewAdapter extends RecyclerView.Adapter {
193221

194222
encodedCodesGenerator.add(project.getShoppingCart());
195223
codes = encodedCodesGenerator.generate();
196-
updateExplanationText(codes.size());
197224
}
198225

199226
@NonNull
200227
@Override
201-
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
202-
return new ViewHolder(new BarcodeView(getContext()));
228+
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
229+
return new ViewHolder(View.inflate(getContext(), R.layout.snabble_item_encodedcodes, null));
203230
}
204231

205232
@Override
206-
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
207-
BarcodeView barcodeView = (BarcodeView)holder.itemView;
233+
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
234+
boolean smallScreen = explanationText2.getVisibility() == View.GONE;
235+
DisplayMetrics dm = getResources().getDisplayMetrics();
236+
237+
holder.itemView.setLayoutParams(new LinearLayout.LayoutParams(
238+
ViewGroup.LayoutParams.MATCH_PARENT,
239+
ViewGroup.LayoutParams.WRAP_CONTENT));
240+
241+
if (position == 0) {
242+
if (codes.size() > 1) {
243+
holder.title.setText(getResources().getString(R.string.Snabble_QRCode_showTheseCodes, getItemCount()));
244+
} else {
245+
holder.title.setText(R.string.Snabble_QRCode_showThisCode);
246+
}
247+
} else {
248+
if (explanationText2.getVisibility() == View.GONE) {
249+
holder.title.setVisibility(View.GONE);
250+
} else {
251+
holder.title.setVisibility(View.VISIBLE);
252+
holder.title.setText(getResources().getString(R.string.Snabble_QRCode_entry_title, (position + 1)));
253+
}
254+
}
208255

209-
int h = scrollContainer.getHeight();
210-
int barcodeHeight = codes.size() == 1 ? h : h - h / 5;
256+
int offsetH = holder.title.getVisibility() != View.GONE ? (int) (48 * dm.density) : 0;
257+
int h = scrollContainer.getHeight() - offsetH;
258+
int barcodeHeight = codes.size() == 1 ? h : h - (smallScreen ? 0 : h / 4);
211259

212260
if (maxSizeMm > 0) {
213-
DisplayMetrics dm = getResources().getDisplayMetrics();
214261
float pixelsPerMmX = dm.xdpi / 25.4f;
215262
int size = (int) (pixelsPerMmX * maxSizeMm);
216263
size = Math.min(barcodeHeight, size);
217264

218-
barcodeView.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, size));
265+
holder.barcodeView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, size));
219266
} else {
220-
barcodeView.setLayoutParams(new RecyclerView.LayoutParams(
267+
holder.barcodeView.setLayoutParams(new LinearLayout.LayoutParams(
221268
ViewGroup.LayoutParams.MATCH_PARENT,
222269
barcodeHeight));
223270
}
224271

225-
barcodeView.setFormat(BarcodeFormat.QR_CODE);
226-
227-
int padding = Math.round(12.0f * getResources().getDisplayMetrics().density);
228-
barcodeView.setPadding(padding, padding, padding, padding);
272+
if (!smallScreen) {
273+
int padding = Math.round(12.0f * getResources().getDisplayMetrics().density);
274+
holder.barcodeView.setPadding(padding, padding, padding, padding);
275+
}
229276

230-
barcodeView.setText(codes.get(position));
277+
holder.barcodeView.setFormat(BarcodeFormat.QR_CODE);
278+
holder.barcodeView.setText(codes.get(position));
231279
}
232280

233281
@Override
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:layout_width="match_parent"
4+
android:layout_height="wrap_content"
5+
android:orientation="vertical">
6+
<TextView android:id="@+id/title"
7+
android:layout_width="match_parent"
8+
android:layout_height="wrap_content"
9+
android:gravity="center"
10+
android:text="@string/Snabble.QRCode.showThisCode"
11+
android:textColor="@color/snabble_textColorDark"
12+
android:textStyle="bold"
13+
android:paddingLeft="24dp"
14+
android:paddingRight="24dp"
15+
android:textSize="17sp" />
16+
17+
<io.snabble.sdk.ui.scanner.BarcodeView android:id="@+id/barcode"
18+
android:layout_width="match_parent"
19+
android:layout_height="wrap_content" />
20+
</LinearLayout>
21+

ui/src/main/res/layout/snabble_view_checkout_encodedcodes.xml

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,10 @@
55
android:layout_height="match_parent"
66
android:background="#ffffff">
77

8-
9-
<TextView
10-
android:id="@+id/explanation1"
11-
android:layout_width="wrap_content"
12-
android:layout_height="wrap_content"
13-
android:gravity="center"
14-
android:layout_centerHorizontal="true"
15-
android:layout_alignParentTop="true"
16-
android:text="@string/Snabble.QRCode.showThisCode"
17-
android:textColor="@color/snabble_textColorDark"
18-
android:layout_marginTop="16dp"
19-
android:layout_marginLeft="24dp"
20-
android:layout_marginRight="24dp"
21-
android:textSize="17sp" />
22-
238
<FrameLayout
249
android:layout_width="match_parent"
2510
android:layout_height="match_parent"
2611
android:layout_above="@+id/pay_amount"
27-
android:layout_below="@+id/explanation1"
2812
android:minHeight="200dp"
2913
android:id="@+id/scroll_container">
3014

@@ -58,11 +42,14 @@
5842
android:layout_marginBottom="16dp"
5943
android:textSize="14sp" />
6044

61-
<Button style="@style/SnabbleButton.TextButton"
45+
<Button style="@style/SnabbleButton"
6246
android:id="@+id/paid"
63-
android:layout_width="wrap_content"
47+
android:layout_width="match_parent"
6448
android:layout_height="wrap_content"
6549
android:layout_alignParentBottom="true"
6650
android:layout_centerHorizontal="true"
51+
android:layout_marginBottom="12dp"
52+
android:layout_marginLeft="16dp"
53+
android:layout_marginRight="16dp"
6754
android:text="@string/Snabble.QRCode.didPay" />
6855
</RelativeLayout>

ui/src/main/res/layout/snabble_view_receipt_list.xml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<merge xmlns:android="http://schemas.android.com/apk/res/android">
33
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
4-
xmlns:android="http://schemas.android.com/apk/res/android"
54
android:id="@+id/swipe_refresh_layout"
65
android:layout_width="match_parent"
76
android:layout_height="match_parent">
@@ -21,5 +20,5 @@
2120
android:textSize="17sp"
2221
android:id="@+id/empty_state"
2322
android:visibility="gone"
24-
android:text="@string/Snabble.Receipt.noReceipt"/>
23+
android:text="@string/Snabble.Receipts.noReceipt"/>
2524
</merge>

0 commit comments

Comments
 (0)