Skip to content

Commit 864de9a

Browse files
committed
List divider added for tablet and landscape mode.
1 parent a82b934 commit 864de9a

File tree

11 files changed

+444
-3
lines changed

11 files changed

+444
-3
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.nmc.android.utils
2+
3+
import android.content.res.Configuration
4+
import com.owncloud.android.MainApp
5+
import com.owncloud.android.R
6+
7+
object DisplayUtils {
8+
9+
@JvmStatic
10+
fun isShowDividerForList(): Boolean = isTablet() || isLandscapeOrientation()
11+
12+
@JvmStatic
13+
fun isTablet(): Boolean = MainApp.getAppContext().resources.getBoolean(R.bool.isTablet)
14+
15+
@JvmStatic
16+
fun isLandscapeOrientation(): Boolean =
17+
MainApp.getAppContext().resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
18+
}

app/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import android.content.Intent;
3131
import android.content.IntentFilter;
3232
import android.content.ServiceConnection;
33+
import android.content.res.Configuration;
3334
import android.os.Bundle;
3435
import android.os.IBinder;
3536
import android.view.Menu;
@@ -56,11 +57,13 @@
5657
import com.owncloud.android.operations.CheckCurrentCredentialsOperation;
5758
import com.owncloud.android.ui.adapter.UploadListAdapter;
5859
import com.owncloud.android.ui.decoration.MediaGridItemDecoration;
60+
import com.owncloud.android.ui.decoration.SimpleListItemDividerDecoration;
5961
import com.owncloud.android.utils.FilesSyncHelper;
6062
import com.owncloud.android.utils.theme.ViewThemeUtils;
6163

6264
import javax.inject.Inject;
6365

66+
import androidx.annotation.NonNull;
6467
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
6568
import androidx.recyclerview.widget.GridLayoutManager;
6669
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
@@ -108,6 +111,8 @@ public class UploadListActivity extends FileActivity {
108111

109112
private UploadListLayoutBinding binding;
110113

114+
private SimpleListItemDividerDecoration simpleListItemDividerDecoration;
115+
111116
public static Intent createIntent(OCFile file, User user, Integer flag, Context context) {
112117
Intent intent = new Intent(context, UploadListActivity.class);
113118
if (flag != null) {
@@ -172,6 +177,8 @@ private void setupContent() {
172177
int spacing = getResources().getDimensionPixelSize(R.dimen.media_grid_spacing);
173178
binding.list.addItemDecoration(new MediaGridItemDecoration(spacing));
174179
binding.list.setLayoutManager(lm);
180+
simpleListItemDividerDecoration = new SimpleListItemDividerDecoration(this, R.drawable.item_divider, true);
181+
addListItemDecorator();
175182
binding.list.setAdapter(uploadListAdapter);
176183

177184
viewThemeUtils.androidx.themeSwipeRefreshLayout(swipeListRefreshLayout);
@@ -180,6 +187,23 @@ private void setupContent() {
180187
loadItems();
181188
}
182189

190+
private void addListItemDecorator() {
191+
if (com.nmc.android.utils.DisplayUtils.isShowDividerForList()) {
192+
//check and remove divider item decorator if exist then add item decorator
193+
removeListDividerDecorator();
194+
binding.list.addItemDecoration(simpleListItemDividerDecoration);
195+
}
196+
}
197+
198+
/**
199+
* method to remove the divider item decorator
200+
*/
201+
private void removeListDividerDecorator() {
202+
if (binding.list.getItemDecorationCount() > 0) {
203+
binding.list.removeItemDecoration(simpleListItemDividerDecoration);
204+
}
205+
}
206+
183207
private void loadItems() {
184208
uploadListAdapter.loadUploadItemsFromDb();
185209

@@ -362,4 +386,20 @@ public void onReceive(Context context, Intent intent) {
362386
});
363387
}
364388
}
389+
390+
@Override
391+
public void onConfigurationChanged(@NonNull Configuration newConfig) {
392+
super.onConfigurationChanged(newConfig);
393+
//this should only run when device is not tablet because we are adding dividers in tablet for both the
394+
// orientations
395+
if (!com.nmc.android.utils.DisplayUtils.isTablet()) {
396+
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
397+
//add the divider item decorator when orientation is landscape
398+
addListItemDecorator();
399+
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
400+
//remove the divider item decorator when orientation is portrait
401+
removeListDividerDecorator();
402+
}
403+
}
404+
}
365405
}

app/src/main/java/com/owncloud/android/ui/decoration/SimpleListItemDividerDecoration.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import android.util.DisplayMetrics;
2929
import android.view.View;
3030

31+
import androidx.core.content.ContextCompat;
3132
import androidx.recyclerview.widget.DividerItemDecoration;
3233
import androidx.recyclerview.widget.RecyclerView;
3334

@@ -39,7 +40,8 @@ public class SimpleListItemDividerDecoration extends DividerItemDecoration {
3940

4041
private final Rect bounds = new Rect();
4142
private Drawable divider;
42-
private int leftPadding;
43+
private int leftPadding = 0;
44+
private boolean hasFooter;
4345

4446
/**
4547
* Default divider will be used
@@ -52,6 +54,17 @@ public SimpleListItemDividerDecoration(Context context) {
5254
styledAttributes.recycle();
5355
}
5456

57+
/**
58+
* Custom divider will be used
59+
*
60+
* @param hasFooter if recyclerview has footer and no divider should be shown for footer then pass true else false
61+
*/
62+
public SimpleListItemDividerDecoration(Context context, int resId, boolean hasFooter) {
63+
super(context, DividerItemDecoration.VERTICAL);
64+
this.hasFooter = hasFooter;
65+
divider = ContextCompat.getDrawable(context, resId);
66+
}
67+
5568
@Override
5669
public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
5770
canvas.save();
@@ -65,7 +78,12 @@ public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state)
6578
right = parent.getWidth();
6679
}
6780

68-
final int childCount = parent.getChildCount();
81+
int childCount = parent.getChildCount();
82+
83+
if (hasFooter) {
84+
childCount = childCount - 1;
85+
}
86+
6987
for (int i = 0; i < childCount; i++) {
7088
final View child = parent.getChildAt(i);
7189
parent.getDecoratedBoundsWithMargins(child, bounds);

app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java

Lines changed: 124 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import android.app.Activity;
2828
import android.content.Context;
2929
import android.content.Intent;
30+
import android.content.res.Configuration;
3031
import android.os.AsyncTask;
3132
import android.os.Bundle;
3233
import android.os.Handler;
@@ -41,6 +42,7 @@
4142
import android.view.MenuItem;
4243
import android.view.View;
4344
import android.view.ViewGroup;
45+
import android.view.ViewTreeObserver;
4446
import android.widget.AbsListView;
4547
import android.widget.Toast;
4648

@@ -59,6 +61,7 @@
5961
import com.nextcloud.client.jobs.BackgroundJobManager;
6062
import com.nextcloud.client.network.ClientFactory;
6163
import com.nextcloud.client.preferences.AppPreferences;
64+
import com.nextcloud.client.preferences.AppPreferencesImpl;
6265
import com.nextcloud.client.utils.Throttler;
6366
import com.nextcloud.common.NextcloudClient;
6467
import com.nextcloud.ui.fileactions.FileActionsBottomSheet;
@@ -90,6 +93,8 @@
9093
import com.owncloud.android.ui.activity.UploadFilesActivity;
9194
import com.owncloud.android.ui.adapter.CommonOCFileListAdapterInterface;
9295
import com.owncloud.android.ui.adapter.OCFileListAdapter;
96+
import com.owncloud.android.ui.decoration.MediaGridItemDecoration;
97+
import com.owncloud.android.ui.decoration.SimpleListItemDividerDecoration;
9398
import com.owncloud.android.ui.dialog.ChooseRichDocumentsTemplateDialogFragment;
9499
import com.owncloud.android.ui.dialog.ChooseTemplateDialogFragment;
95100
import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
@@ -230,6 +235,9 @@ public class OCFileListFragment extends ExtendedListFragment implements
230235
protected String mLimitToMimeType;
231236
private FloatingActionButton mFabMain;
232237

238+
private SimpleListItemDividerDecoration simpleListItemDividerDecoration;
239+
private MediaGridItemDecoration mediaGridItemDecoration;
240+
233241
@Inject DeviceInfo deviceInfo;
234242

235243
protected enum MenuItemAddRemove {
@@ -243,6 +251,13 @@ protected enum MenuItemAddRemove {
243251

244252
private List<MenuItem> mOriginalMenuItems = new ArrayList<>();
245253

254+
private int maxColumnSizeLandscape = 5;
255+
256+
//this variable will help us to provide number of span count for grid view
257+
//the width for single item is approx to 360
258+
private static final int GRID_ITEM_DEFAULT_WIDTH = 360;
259+
private static final int DEFAULT_FALLBACK_SPAN_COUNT = 1;
260+
246261
@Override
247262
public void onCreate(Bundle savedInstanceState) {
248263
super.onCreate(savedInstanceState);
@@ -438,6 +453,10 @@ protected void setAdapter(Bundle args) {
438453
viewThemeUtils
439454
);
440455

456+
simpleListItemDividerDecoration = new SimpleListItemDividerDecoration(getContext(), R.drawable.item_divider, true);
457+
int spacing = getResources().getDimensionPixelSize(R.dimen.media_grid_spacing);
458+
mediaGridItemDecoration = new MediaGridItemDecoration(spacing);
459+
441460
setRecyclerViewAdapter(mAdapter);
442461

443462
fastScrollUtils.applyFastScroll(getRecyclerView());
@@ -554,7 +573,7 @@ public void uploadFiles() {
554573
getActivity(),
555574
((FileActivity) getActivity()).getUser().orElseThrow(RuntimeException::new),
556575
FileDisplayActivity.REQUEST_CODE__SELECT_FILES_FROM_FILE_SYSTEM,
557-
getCurrentFile().isEncrypted()
576+
getCurrentFile().isEncrypted()
558577
);
559578
}
560579

@@ -1440,6 +1459,7 @@ public void switchToListView() {
14401459
if (isGridEnabled()) {
14411460
switchLayoutManager(false);
14421461
}
1462+
addRemoveRecyclerViewItemDecorator();
14431463
}
14441464

14451465
public void setGridAsPreferred() {
@@ -1451,6 +1471,33 @@ public void switchToGridView() {
14511471
if (!isGridEnabled()) {
14521472
switchLayoutManager(true);
14531473
}
1474+
addRemoveRecyclerViewItemDecorator();
1475+
}
1476+
1477+
private void addRemoveRecyclerViewItemDecorator() {
1478+
if (getRecyclerView().getLayoutManager() instanceof GridLayoutManager) {
1479+
removeItemDecorator();
1480+
if (getRecyclerView().getItemDecorationCount() == 0) {
1481+
getRecyclerView().addItemDecoration(mediaGridItemDecoration);
1482+
int padding = getResources().getDimensionPixelSize(R.dimen.grid_recyclerview_padding);
1483+
getRecyclerView().setPadding(padding, padding, padding, padding);
1484+
}
1485+
} else {
1486+
removeItemDecorator();
1487+
if (getRecyclerView().getItemDecorationCount() == 0 && com.nmc.android.utils.DisplayUtils.isShowDividerForList()) {
1488+
getRecyclerView().addItemDecoration(simpleListItemDividerDecoration);
1489+
getRecyclerView().setPadding(0, 0, 0, 0);
1490+
}
1491+
}
1492+
}
1493+
1494+
/**
1495+
* method to remove the item decorator
1496+
*/
1497+
private void removeItemDecorator() {
1498+
while (getRecyclerView().getItemDecorationCount() > 0) {
1499+
getRecyclerView().removeItemDecorationAt(0);
1500+
}
14541501
}
14551502

14561503
public void switchLayoutManager(boolean grid) {
@@ -1481,12 +1528,40 @@ public int getSpanSize(int position) {
14811528
}
14821529

14831530
getRecyclerView().setLayoutManager(layoutManager);
1531+
updateSpanCount(getResources().getConfiguration());
14841532
getRecyclerView().scrollToPosition(position);
14851533
getAdapter().setGridView(grid);
14861534
getRecyclerView().setAdapter(getAdapter());
14871535
getAdapter().notifyDataSetChanged();
14881536
}
14891537

1538+
/**
1539+
* method will calculate the number of spans required for grid item and will update the span accordingly
1540+
*
1541+
* @param isGrid
1542+
*/
1543+
private void calculateAndUpdateSpanCount(boolean isGrid) {
1544+
getRecyclerView().getViewTreeObserver().addOnGlobalLayoutListener(
1545+
new ViewTreeObserver.OnGlobalLayoutListener() {
1546+
@Override
1547+
public void onGlobalLayout() {
1548+
getRecyclerView().getViewTreeObserver().removeOnGlobalLayoutListener(this);
1549+
if (isGrid) {
1550+
int viewWidth = getRecyclerView().getMeasuredWidth();
1551+
int newSpanCount = viewWidth / GRID_ITEM_DEFAULT_WIDTH;
1552+
RecyclerView.LayoutManager layoutManager = getRecyclerView().getLayoutManager();
1553+
if (layoutManager instanceof GridLayoutManager) {
1554+
if (newSpanCount < 1) {
1555+
newSpanCount = DEFAULT_FALLBACK_SPAN_COUNT;
1556+
}
1557+
((GridLayoutManager) layoutManager).setSpanCount(newSpanCount);
1558+
layoutManager.requestLayout();
1559+
}
1560+
}
1561+
}
1562+
});
1563+
}
1564+
14901565
public CommonOCFileListAdapterInterface getCommonAdapter() {
14911566
return mAdapter;
14921567
}
@@ -2024,4 +2099,52 @@ public void setFabEnabled(final boolean enabled) {
20242099
public boolean isEmpty() {
20252100
return mAdapter == null || mAdapter.isEmpty();
20262101
}
2102+
2103+
@Override
2104+
public void onConfigurationChanged(@NonNull Configuration newConfig) {
2105+
super.onConfigurationChanged(newConfig);
2106+
if (getAdapter() != null) {
2107+
getAdapter().notifyDataSetChanged();
2108+
}
2109+
updateSpanCount(newConfig);
2110+
}
2111+
2112+
/**
2113+
* method will update the span count on basis of device orientation for the file listing
2114+
*
2115+
* @param newConfig current configuration
2116+
*/
2117+
private void updateSpanCount(Configuration newConfig) {
2118+
//this should only run when current view is not media gallery
2119+
if (getAdapter() != null) {
2120+
int maxColumnSize = (int) AppPreferencesImpl.DEFAULT_GRID_COLUMN;
2121+
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
2122+
//add the divider item decorator when orientation is landscape and device is not tablet
2123+
//because we don't have to add divider again as it is already added
2124+
if (!com.nmc.android.utils.DisplayUtils.isTablet()) {
2125+
addRemoveRecyclerViewItemDecorator();
2126+
}
2127+
maxColumnSize = maxColumnSizeLandscape;
2128+
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
2129+
//remove the divider item decorator when orientation is portrait and when device is not tablet
2130+
//because we have to show divider in both landscape and portrait mode
2131+
if (!com.nmc.android.utils.DisplayUtils.isTablet()) {
2132+
removeItemDecorator();
2133+
}
2134+
maxColumnSize = (int) AppPreferencesImpl.DEFAULT_GRID_COLUMN;
2135+
}
2136+
2137+
if (isGridEnabled()) {
2138+
//for tablet calculate size on the basis of screen width
2139+
if (com.nmc.android.utils.DisplayUtils.isTablet()) {
2140+
calculateAndUpdateSpanCount(true);
2141+
} else {
2142+
//and for phones directly show the hardcoded column size
2143+
if (getRecyclerView().getLayoutManager() instanceof GridLayoutManager) {
2144+
((GridLayoutManager) getRecyclerView().getLayoutManager()).setSpanCount(maxColumnSize);
2145+
}
2146+
}
2147+
}
2148+
}
2149+
}
20272150
}

0 commit comments

Comments
 (0)