Merge pull request #4298 from ByteHamster/tablet-layout

Tablet layout
This commit is contained in:
H. Lehmann 2020-07-21 11:03:41 +02:00 committed by GitHub
commit 602cd71dd8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 194 additions and 37 deletions

View File

@ -31,6 +31,7 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.event.MessageEvent;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.util.StorageUtils;
import de.danoeh.antennapod.core.util.ThemeUtils;
import de.danoeh.antennapod.core.util.download.AutoUpdateManager;
import de.danoeh.antennapod.dialog.RatingDialog;
import de.danoeh.antennapod.fragment.AddFeedFragment;
@ -68,9 +69,9 @@ public class MainActivity extends CastEnabledActivity {
public static final String EXTRA_OPEN_PLAYER = "open_player";
public static final String EXTRA_REFRESH_ON_START = "refresh_on_start";
private DrawerLayout drawerLayout;
private @Nullable DrawerLayout drawerLayout;
private @Nullable ActionBarDrawerToggle drawerToggle;
private View navDrawer;
private ActionBarDrawerToggle drawerToggle;
private LockableBottomSheetBehavior sheetBehavior;
private long lastBackButtonPressTime = 0;
private RecyclerView.RecycledViewPool recycledViewPool = new RecyclerView.RecycledViewPool();
@ -97,8 +98,14 @@ public class MainActivity extends CastEnabledActivity {
navDrawer = findViewById(R.id.navDrawerFragment);
final FragmentManager fm = getSupportFragmentManager();
fm.addOnBackStackChangedListener(() ->
drawerToggle.setDrawerIndicatorEnabled(fm.getBackStackEntryCount() == 0));
fm.addOnBackStackChangedListener(() -> {
boolean showArrow = fm.getBackStackEntryCount() != 0;
if (drawerToggle != null) { // Tablet layout does not have a drawer
drawerToggle.setDrawerIndicatorEnabled(!showArrow);
} else if (getActionBar() != null) {
getActionBar().setDisplayHomeAsUpEnabled(showArrow);
}
});
if (fm.findFragmentByTag(MAIN_FRAGMENT_TAG) == null) {
String lastFragment = NavDrawerFragment.getLastNavFragment(this);
@ -151,12 +158,18 @@ public class MainActivity extends CastEnabledActivity {
@Override
public void setSupportActionBar(@Nullable Toolbar toolbar) {
drawerLayout.removeDrawerListener(drawerToggle);
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar,
R.string.drawer_open, R.string.drawer_close);
drawerLayout.addDrawerListener(drawerToggle);
drawerToggle.syncState();
drawerToggle.setDrawerIndicatorEnabled(getSupportFragmentManager().getBackStackEntryCount() == 0);
if (drawerLayout != null) { // Tablet layout does not have a drawer
drawerLayout.removeDrawerListener(drawerToggle);
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar,
R.string.drawer_open, R.string.drawer_close);
drawerLayout.addDrawerListener(drawerToggle);
drawerToggle.syncState();
drawerToggle.setDrawerIndicatorEnabled(getSupportFragmentManager().getBackStackEntryCount() == 0);
} else if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
toolbar.setNavigationIcon(null);
} else {
toolbar.setNavigationIcon(ThemeUtils.getDrawableFromAttr(this, R.attr.homeAsUpIndicator));
}
super.setSupportActionBar(toolbar);
}
@ -164,7 +177,11 @@ public class MainActivity extends CastEnabledActivity {
SharedPreferences prefs = getSharedPreferences(PREF_NAME, MODE_PRIVATE);
if (prefs.getBoolean(PREF_IS_FIRST_LAUNCH, true)) {
loadFragment(AddFeedFragment.TAG, null);
new Handler().postDelayed(() -> drawerLayout.openDrawer(navDrawer), 1500);
new Handler().postDelayed(() -> {
if (drawerLayout != null) { // Tablet layout does not have a drawer
drawerLayout.openDrawer(navDrawer);
}
}, 1500);
// for backward compatibility, we only change defaults for fresh installs
UserPreferences.setUpdateInterval(12);
@ -258,7 +275,10 @@ public class MainActivity extends CastEnabledActivity {
// not commit anything in an AsyncTask, but that's a bigger
// change than we want now.
t.commitAllowingStateLoss();
drawerLayout.closeDrawer(navDrawer);
if (drawerLayout != null) { // Tablet layout does not have a drawer
drawerLayout.closeDrawer(navDrawer);
}
}
public void loadChildFragment(Fragment fragment, TransitionEffect transition) {
@ -292,13 +312,17 @@ public class MainActivity extends CastEnabledActivity {
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
drawerToggle.syncState();
if (drawerToggle != null) { // Tablet layout does not have a drawer
drawerToggle.syncState();
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
drawerToggle.onConfigurationChanged(newConfig);
if (drawerToggle != null) { // Tablet layout does not have a drawer
drawerToggle.onConfigurationChanged(newConfig);
}
}
@Override
@ -351,7 +375,7 @@ public class MainActivity extends CastEnabledActivity {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (drawerToggle.onOptionsItemSelected(item)) {
if (drawerToggle != null && drawerToggle.onOptionsItemSelected(item)) { // Tablet layout does not have a drawer
return true;
} else if (item.getItemId() == android.R.id.home) {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
@ -374,7 +398,9 @@ public class MainActivity extends CastEnabledActivity {
} else {
switch (UserPreferences.getBackButtonBehavior()) {
case OPEN_DRAWER:
drawerLayout.openDrawer(navDrawer);
if (drawerLayout != null) { // Tablet layout does not have drawer
drawerLayout.openDrawer(navDrawer);
}
break;
case SHOW_PROMPT:
new AlertDialog.Builder(this)

View File

@ -3,6 +3,7 @@ package de.danoeh.antennapod.fragment;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.LightingColorFilter;
import android.net.Uri;
import android.os.Bundle;
@ -47,9 +48,6 @@ import io.reactivex.MaybeOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
/**
* Displays information about a feed.
@ -71,6 +69,8 @@ public class FeedInfoFragment extends Fragment {
private TextView txtvUrl;
private TextView txtvAuthorHeader;
private ImageView imgvBackground;
private View infoContainer;
private View header;
private Menu optionsMenu;
private ToolbarIconTintManager iconTintManager;
@ -124,6 +124,8 @@ public class FeedInfoFragment extends Fragment {
txtvTitle = root.findViewById(R.id.txtvTitle);
txtvAuthorHeader = root.findViewById(R.id.txtvAuthor);
imgvBackground = root.findViewById(R.id.imgvBackground);
header = root.findViewById(R.id.headerContainer);
infoContainer = root.findViewById(R.id.infoContainer);
root.findViewById(R.id.butShowInfo).setVisibility(View.INVISIBLE);
root.findViewById(R.id.butShowSettings).setVisibility(View.INVISIBLE);
// https://github.com/bumptech/glide/issues/529
@ -159,6 +161,15 @@ public class FeedInfoFragment extends Fragment {
}, error -> Log.d(TAG, Log.getStackTraceString(error)), () -> { });
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
int horizontalSpacing = (int) getResources().getDimension(R.dimen.additional_horizontal_spacing);
header.setPadding(horizontalSpacing, header.getPaddingTop(), horizontalSpacing, header.getPaddingBottom());
infoContainer.setPadding(horizontalSpacing, infoContainer.getPaddingTop(),
horizontalSpacing, infoContainer.getPaddingBottom());
}
private void showFeed() {
Log.d(TAG, "Language is " + feed.getLanguage());
Log.d(TAG, "Author is " + feed.getAuthor());

View File

@ -2,6 +2,7 @@ package de.danoeh.antennapod.fragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Configuration;
import android.graphics.LightingColorFilter;
import android.os.Bundle;
import android.util.Log;
@ -98,6 +99,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
private TextView txtvAuthor;
private ImageButton butShowInfo;
private ImageButton butShowSettings;
private View header;
private Menu optionsMenu;
private ToolbarIconTintManager iconTintManager;
@ -155,6 +157,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
butShowSettings = root.findViewById(R.id.butShowSettings);
txtvInformation = root.findViewById(R.id.txtvInformation);
txtvFailure = root.findViewById(R.id.txtvFailure);
header = root.findViewById(R.id.headerContainer);
AppBarLayout appBar = root.findViewById(R.id.appBar);
CollapsingToolbarLayout collapsingToolbar = root.findViewById(R.id.collapsing_toolbar);
@ -245,6 +248,13 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
int horizontalSpacing = (int) getResources().getDimension(R.dimen.additional_horizontal_spacing);
header.setPadding(horizontalSpacing, header.getPaddingTop(), horizontalSpacing, header.getPaddingBottom());
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (!super.onOptionsItemSelected(item)) {

View File

@ -90,7 +90,7 @@ public class SubscriptionFragment extends Fragment {
View root = inflater.inflate(R.layout.fragment_subscriptions, container, false);
((AppCompatActivity) getActivity()).setSupportActionBar(root.findViewById(R.id.toolbar));
subscriptionGridLayout = root.findViewById(R.id.subscriptions_grid);
subscriptionGridLayout.setNumColumns(prefs.getInt(PREF_NUM_COLUMNS, 3));
subscriptionGridLayout.setNumColumns(prefs.getInt(PREF_NUM_COLUMNS, getDefaultNumOfColumns()));
registerForContextMenu(subscriptionGridLayout);
subscriptionAddButton = root.findViewById(R.id.subscriptions_add);
progressBar = root.findViewById(R.id.progLoading);
@ -102,7 +102,7 @@ public class SubscriptionFragment extends Fragment {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.subscriptions, menu);
int columns = prefs.getInt(PREF_NUM_COLUMNS, 3);
int columns = prefs.getInt(PREF_NUM_COLUMNS, getDefaultNumOfColumns());
menu.findItem(R.id.subscription_num_columns_2).setChecked(columns == 2);
menu.findItem(R.id.subscription_num_columns_3).setChecked(columns == 3);
menu.findItem(R.id.subscription_num_columns_4).setChecked(columns == 4);
@ -200,6 +200,10 @@ public class SubscriptionFragment extends Fragment {
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
}
private int getDefaultNumOfColumns() {
return getResources().getInteger(R.integer.subscriptions_default_num_of_columns);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);

View File

@ -2,6 +2,7 @@ package de.danoeh.antennapod.view;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.util.AttributeSet;
import android.view.View;
import androidx.appcompat.view.ContextThemeWrapper;
@ -39,6 +40,14 @@ public class EpisodeItemListRecyclerView extends RecyclerView {
setLayoutManager(layoutManager);
setHasFixedSize(true);
addItemDecoration(new HorizontalDividerItemDecoration.Builder(getContext()).build());
setClipToPadding(false);
}
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
int horizontalSpacing = (int) getResources().getDimension(R.dimen.additional_horizontal_spacing);
setPadding(horizontalSpacing, getPaddingTop(), horizontalSpacing, getPaddingBottom());
}
public void saveScrollPosition(String tag) {

View File

@ -33,11 +33,15 @@ public abstract class ToolbarIconTintManager implements AppBarLayout.OnOffsetCha
public void updateTint() {
if (isTinted) {
doTint(new ContextThemeWrapper(context, R.style.Theme_AntennaPod_Dark));
toolbar.getNavigationIcon().setColorFilter(0xffffffff, PorterDuff.Mode.SRC_ATOP);
if (toolbar.getNavigationIcon() != null) { // Tablets do not show a navigation icon
toolbar.getNavigationIcon().setColorFilter(0xffffffff, PorterDuff.Mode.SRC_ATOP);
}
toolbar.getOverflowIcon().setColorFilter(0xffffffff, PorterDuff.Mode.SRC_ATOP);
} else {
doTint(context);
toolbar.getNavigationIcon().clearColorFilter();
if (toolbar.getNavigationIcon() != null) { // Tablets do not show a navigation icon
toolbar.getNavigationIcon().clearColorFilter();
}
toolbar.getOverflowIcon().clearColorFilter();
}
}

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/navDrawerFragment"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:orientation="vertical" />
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="?android:attr/listDivider" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/overview_coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/main_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:foreground="?android:windowContentOverlay"
tools:background="@android:color/holo_red_dark" />
<FrameLayout
android:elevation="8dp"
android:id="@+id/audioplayerFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/windowBackground"
android:visibility="gone"
app:layout_behavior="de.danoeh.antennapod.view.LockableBottomSheetBehavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>

View File

@ -23,9 +23,9 @@
android:layout_below="@+id/txtvInformation"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"
android:clipToPadding="false"
android:paddingTop="@dimen/list_vertical_padding"
android:paddingBottom="@dimen/list_vertical_padding"
android:paddingHorizontal="@dimen/additional_horizontal_spacing"
android:layout_above="@id/loadingMore"
tools:itemCount="13"
tools:listitem="@layout/feeditemlist_item" />

View File

@ -52,6 +52,7 @@
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingHorizontal="@dimen/additional_horizontal_spacing"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<ProgressBar

View File

@ -62,6 +62,8 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/infoContainer"
android:paddingHorizontal="@dimen/additional_horizontal_spacing"
android:orientation="vertical">
<TextView

View File

@ -5,6 +5,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/headerContainer"
android:paddingHorizontal="@dimen/additional_horizontal_spacing"
android:orientation="vertical">
<LinearLayout

View File

@ -5,7 +5,9 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
tools:ignore="InconsistentLayout">
<!-- InconsistentLayout: Tablet layout does not have a drawer -->
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/overview_coordinator_layout"

View File

@ -36,6 +36,7 @@
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingHorizontal="@dimen/additional_horizontal_spacing"
android:layout_below="@id/divider" />
<ProgressBar

View File

@ -36,7 +36,7 @@
android:layout_below="@id/recyclerViewFeeds"
android:layout_marginTop="-4dp"
android:paddingTop="12dp"
android:clipToPadding="false"
android:paddingHorizontal="@dimen/additional_horizontal_spacing"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>

View File

@ -14,9 +14,9 @@
<de.danoeh.antennapod.view.EpisodeItemListRecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingHorizontal="@dimen/additional_horizontal_spacing"
android:layout_below="@id/toolbar"
android:id="@+id/recyclerView"
android:clipToPadding="false"/>
android:id="@+id/recyclerView"/>
<ProgressBar
android:id="@+id/progLoading"

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="subscriptions_default_num_of_columns">5</integer>
</resources>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="additional_horizontal_spacing">56dp</dimen>
</resources>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- increase FAB speed dial label's max width if the screen is wide enough
(300dp ~ 1.875 inch, devices with 3.5-inch screens have a width of ~ 1.9in
so the setup is applicable for most phones)
-->
<dimen name="sd_label_max_width" tools:ignore="MissingDefaultResource, UnusedResources">240dp</dimen>
</resources>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<dimen name="additional_horizontal_spacing">0dp</dimen>
<!--
Overwrites FAB library.
Increase FAB speed dial label's max width if the screen is wide enough
(300dp ~ 1.875 inch, devices with 3.5-inch screens have a width of ~ 1.9in
so the setup is applicable for most phones)
-->
<dimen name="sd_label_max_width" tools:ignore="MissingDefaultResource, UnusedResources">240dp</dimen>
</resources>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="additional_horizontal_spacing">0dp</dimen>
</resources>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="subscriptions_default_num_of_columns">3</integer>
</resources>

View File

@ -6,6 +6,12 @@ function generateText() {
-annotate 0 "$1" /tmp/text.png
}
function generateTabletText() {
echo "$1"
convert -size 1730x350 xc:none -gravity Center -pointsize 80 -fill white -font Lato-Regular \
-annotate 0 "$1" /tmp/text.png
}
function simplePhone() {
generateText "$1"
convert templates/phone.png \
@ -14,6 +20,15 @@ function simplePhone() {
$3
}
function simpleTablet() {
generateTabletText "$1"
convert $2 -resize 1280 "/tmp/resized-image.png"
convert templates/tablet.png \
/tmp/resized-image.png -geometry +227+459 -composite \
/tmp/text.png -geometry +0+0 -composite \
$3
}
function addLayer() {
convert $2 $1 -composite $2
}
@ -27,6 +42,7 @@ function generateScreenshots() {
text3=`cat raw/$language/texts.txt | head -4 | tail -1`
text4=`cat raw/$language/texts.txt | head -5 | tail -1`
text5=`cat raw/$language/texts.txt | head -6 | tail -1`
text6=`cat raw/$language/texts.txt | head -7 | tail -1`
simplePhone "$text0" raw/$language/00.png output/$language/00.png
simplePhone "$text1" raw/$language/01.png output/$language/01.png
@ -42,7 +58,8 @@ function generateScreenshots() {
simplePhone "$text4" raw/$language/04.png output/$language/04.png
simplePhone "$text5" raw/$language/05.png output/$language/05.png
addLayer templates/suggestions.png output/$language/05.png
mogrify -resize 1120 "output/$language/*.png"
simpleTablet "$text6" raw/$language/tablet.png output/$language/tablet.png
mogrify -resize 1120 "output/$language/0*.png"
}
mkdir output 2>/dev/null

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 KiB

View File

@ -4,3 +4,4 @@ Spare Zeit mit\nautomatischen Downloads
Wähle dein\nLieblings-Theme
Passe AntennaPod\nan deine Wünsche an
Entdecke tausende\nneuer Podcasts
Genieße deine Podcasts. Überall. Jederzeit.

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

View File

@ -4,3 +4,4 @@ Save time with\nautomatic downloads
Select the theme\nthat fits best to you
Adapt AntennaPod\nto your needs
Discover thousands\nof great podcasts
Enjoy your podcasts. Anywhere. Anytime.

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 KiB

View File

@ -4,3 +4,4 @@ Bespaar tijd met\nautomatische downloads
Selecteer het thema\ndat het best bij je past
Pas AntennaPod aan\naan jouw wensen
Ontdek honderden\ninteressante podcasts
Enjoy your podcasts. Anywhere. Anytime.

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB