dividers and alignments

nobody knows the trouble i've seen
This commit is contained in:
sk
2023-01-25 22:55:14 +01:00
parent 907c5a2ca1
commit 8bdbb2adef
6 changed files with 164 additions and 111 deletions

View File

@@ -95,8 +95,8 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
private TimelineDefinition[] timelines; private TimelineDefinition[] timelines;
private final Map<Integer, TimelineDefinition> timelinesByMenuItem = new HashMap<>(); private final Map<Integer, TimelineDefinition> timelinesByMenuItem = new HashMap<>();
private SubMenu hashtagsMenu, listsMenu; private SubMenu hashtagsMenu, listsMenu;
private Menu optionsMenu; private PopupMenu overflowPopup;
private MenuInflater optionsMenuInflater; private View overflowActionView = null;
private boolean announcementsBadged, settingsBadged; private boolean announcementsBadged, settingsBadged;
@Override @Override
@@ -153,6 +153,12 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
view.addView(pager, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); view.addView(pager, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
overflowActionView = UiUtils.makeOverflowActionView(getContext());
overflowPopup = new PopupMenu(getContext(), overflowActionView);
overflowPopup.setOnMenuItemClickListener(this::onOptionsItemSelected);
overflowActionView.setOnClickListener(l -> overflowPopup.show());
overflowActionView.setOnTouchListener(overflowPopup.getDragToOpenListener());
return view; return view;
} }
@@ -231,9 +237,49 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
if(GithubSelfUpdater.needSelfUpdating()){ if(GithubSelfUpdater.needSelfUpdating()){
updateUpdateState(GithubSelfUpdater.getInstance().getState()); updateUpdateState(GithubSelfUpdater.getInstance().getState());
} }
new GetLists().setCallback(new Callback<>() {
@Override
public void onSuccess(List<ListTimeline> lists) {
updateList(lists, listItems);
} }
private void addListsToOptionsMenu() { @Override
public void onError(ErrorResponse error) {
error.showToast(getContext());
}
}).exec(accountID);
new GetFollowedHashtags().setCallback(new Callback<>() {
@Override
public void onSuccess(HeaderPaginationList<Hashtag> hashtags) {
updateList(hashtags, hashtagsItems);
}
@Override
public void onError(ErrorResponse error) {
error.showToast(getContext());
}
}).exec(accountID);
new GetAnnouncements(false).setCallback(new Callback<>() {
@Override
public void onSuccess(List<Announcement> result) {
if (result.stream().anyMatch(a -> !a.read)) {
announcementsBadged = true;
announcements.setVisible(false);
announcementsAction.setVisible(true);
}
}
@Override
public void onError(ErrorResponse error) {
error.showToast(getActivity());
}
}).exec(accountID);
}
private void addListsToOverflowMenu() {
Context ctx = getContext(); Context ctx = getContext();
listsMenu.clear(); listsMenu.clear();
listsMenu.getItem().setVisible(listItems.size() > 0); listsMenu.getItem().setVisible(listItems.size() > 0);
@@ -245,7 +291,7 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
}); });
} }
private void addHashtagsToOptionsMenu() { private void addHashtagsToOverflowMenu() {
Context ctx = getContext(); Context ctx = getContext();
hashtagsMenu.clear(); hashtagsMenu.clear();
hashtagsMenu.getItem().setVisible(hashtagsItems.size() > 0); hashtagsMenu.getItem().setVisible(hashtagsItems.size() > 0);
@@ -291,79 +337,45 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
} }
} }
private void createOptionsMenu() { private void updateOverflowMenu() {
optionsMenu.clear(); Menu m = overflowPopup.getMenu();
optionsMenuInflater.inflate(R.menu.home, optionsMenu); m.clear();
announcements = optionsMenu.findItem(R.id.announcements); overflowPopup.inflate(R.menu.home_overflow);
announcementsAction = optionsMenu.findItem(R.id.announcements_action); announcements = m.findItem(R.id.announcements);
settings = optionsMenu.findItem(R.id.settings); settings = m.findItem(R.id.settings);
settingsAction = optionsMenu.findItem(R.id.settings_action); hashtagsMenu = m.findItem(R.id.hashtags).getSubMenu();
hashtagsMenu = optionsMenu.findItem(R.id.hashtags).getSubMenu(); listsMenu = m.findItem(R.id.lists).getSubMenu();
listsMenu = optionsMenu.findItem(R.id.lists).getSubMenu();
announcements.setVisible(!announcementsBadged); announcements.setVisible(!announcementsBadged);
announcementsAction.setVisible(announcementsBadged); announcementsAction.setVisible(announcementsBadged);
settings.setVisible(!settingsBadged); settings.setVisible(!settingsBadged);
settingsAction.setVisible(settingsBadged); settingsAction.setVisible(settingsBadged);
UiUtils.enableOptionsMenuIcons(getContext(), optionsMenu, UiUtils.enablePopupMenuIcons(getContext(), overflowPopup);
R.id.overflow, R.id.announcements_action, R.id.settings_action);
addListsToOptionsMenu(); addListsToOverflowMenu();
addHashtagsToOptionsMenu(); addHashtagsToOverflowMenu();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
m.setGroupDividerEnabled(true);
}
} }
@Override @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
this.optionsMenu = menu; inflater.inflate(R.menu.home, menu);
this.optionsMenuInflater = inflater;
createOptionsMenu();
new GetLists().setCallback(new Callback<>() { menu.findItem(R.id.overflow).setActionView(overflowActionView);
@Override announcementsAction = menu.findItem(R.id.announcements_action);
public void onSuccess(List<ListTimeline> lists) { settingsAction = menu.findItem(R.id.settings_action);
updateList(lists, listItems);
}
@Override updateOverflowMenu();
public void onError(ErrorResponse error) {
error.showToast(getContext());
}
}).exec(accountID);
new GetFollowedHashtags().setCallback(new Callback<>() {
@Override
public void onSuccess(HeaderPaginationList<Hashtag> hashtags) {
updateList(hashtags, hashtagsItems);
}
@Override
public void onError(ErrorResponse error) {
error.showToast(getContext());
}
}).exec(accountID);
new GetAnnouncements(false).setCallback(new Callback<>() {
@Override
public void onSuccess(List<Announcement> result) {
if (result.stream().anyMatch(a -> !a.read)) {
announcementsBadged = true;
announcements.setVisible(false);
announcementsAction.setVisible(true);
}
}
@Override
public void onError(ErrorResponse error) {
error.showToast(getActivity());
}
}).exec(accountID);
} }
private <T> void updateList(List<T> addItems, Map<Integer, T> items) { private <T> void updateList(List<T> addItems, Map<Integer, T> items) {
if (addItems.size() == 0) return; if (addItems.size() == 0) return;
for (int i = 0; i < addItems.size(); i++) items.put(View.generateViewId(), addItems.get(i)); for (int i = 0; i < addItems.size(); i++) items.put(View.generateViewId(), addItems.get(i));
createOptionsMenu(); updateOverflowMenu();
} }
private void updateSwitcherMenu() { private void updateSwitcherMenu() {
@@ -427,8 +439,7 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
Hashtag hashtag; Hashtag hashtag;
if (item.getItemId() == R.id.menu_back) { if (item.getItemId() == R.id.menu_back) {
createOptionsMenu(); getToolbar().post(() -> overflowPopup.show());
optionsMenu.performIdentifierAction(R.id.overflow, 0);
return true; return true;
} else if (id == R.id.settings || id == R.id.settings_action) { } else if (id == R.id.settings || id == R.id.settings_action) {
Nav.go(getActivity(), SettingsFragment.class, args); Nav.go(getActivity(), SettingsFragment.class, args);
@@ -563,6 +574,14 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
@Override @Override
public void onDestroyView(){ public void onDestroyView(){
super.onDestroyView(); super.onDestroyView();
if (overflowPopup != null) {
overflowPopup.dismiss();
overflowPopup = null;
}
if (switcherPopup != null) {
switcherPopup.dismiss();
switcherPopup = null;
}
if(GithubSelfUpdater.needSelfUpdating()){ if(GithubSelfUpdater.needSelfUpdating()){
E.unregister(this); E.unregister(this);
} }
@@ -625,10 +644,10 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
if (shouldBeInList) { if (shouldBeInList) {
existingThings.put(existingThing.isPresent() existingThings.put(existingThing.isPresent()
? existingThing.get().getKey() : View.generateViewId(), makeNewThing.get()); ? existingThing.get().getKey() : View.generateViewId(), makeNewThing.get());
createOptionsMenu(); updateOverflowMenu();
} else if (existingThing.isPresent() && !shouldBeInList) { } else if (existingThing.isPresent() && !shouldBeInList) {
existingThings.remove(existingThing.get().getKey()); existingThings.remove(existingThing.get().getKey());
createOptionsMenu(); updateOverflowMenu();
} }
} }

View File

@@ -40,6 +40,8 @@ import android.view.SubMenu;
import android.view.View; import android.view.View;
import android.webkit.MimeTypeMap; import android.webkit.MimeTypeMap;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupMenu; import android.widget.PopupMenu;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
@@ -1111,4 +1113,42 @@ public class UiUtils{
Log.e("reduceSwipeSensitivity", Log.getStackTraceString(ex)); Log.e("reduceSwipeSensitivity", Log.getStackTraceString(ex));
} }
} }
public static View makeOverflowActionView(Context ctx) {
// container needs tooltip, content description
LinearLayout container = new LinearLayout(ctx, null, 0, R.style.Widget_Mastodon_ActionButton_Overflow) {
@Override
public CharSequence getAccessibilityClassName() {
return Button.class.getName();
}
};
// image needs, well, the image, and the paddings
ImageView image = new ImageView(ctx, null, 0, R.style.Widget_Mastodon_ActionButton_Overflow);
image.setDuplicateParentStateEnabled(true);
image.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
image.setClickable(false);
image.setFocusable(false);
image.setEnabled(false);
// problem: as per overflow action button defaults, the padding on left and right is unequal
// so (however the native overflow button manages this), the ripple background is off-center
// workaround: set both paddings to the smaller one…
int end = image.getPaddingEnd();
int start = image.getPaddingStart();
int paddingDiff = end - start; // what's missing to the long padding
image.setPaddingRelative(start, image.getPaddingTop(), start, image.getPaddingBottom());
// …and make up for the additional padding using a negative margin in a container
container.setPaddingRelative(0, 0, paddingDiff, 0);
container.setBackground(null);
container.setClickable(true);
container.setFocusable(true);
container.addView(image);
// fucking finally
return container;
}
} }

View File

@@ -3,23 +3,16 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingTop="16dp" android:paddingTop="11dp"
android:paddingRight="16dp" android:paddingEnd="4dp"
android:paddingLeft="16dp"> android:paddingStart="16dp">
<!--
okay look, i know marginEnd = -9.9dp looks silly, but i was trying *really* hard to align this
more button to the overflow button in the action bar and -9.9 was the best i could come up with
after trying for way too long
-->
<ImageView <ImageView
android:id="@+id/more" android:id="@+id/more"
android:layout_width="36dp" android:layout_width="36dp"
android:layout_height="36dp" android:layout_height="36dp"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_marginTop="-5dp"
android:layout_marginEnd="-9.9dp"
android:background="?android:actionBarItemBackground" android:background="?android:actionBarItemBackground"
android:contentDescription="@string/more_options" android:contentDescription="@string/more_options"
android:scaleType="center" android:scaleType="center"
@@ -30,7 +23,6 @@
android:id="@+id/delete_notification" android:id="@+id/delete_notification"
android:layout_width="36dp" android:layout_width="36dp"
android:layout_height="36dp" android:layout_height="36dp"
android:layout_marginTop="-5dp"
android:layout_toStartOf="@id/more" android:layout_toStartOf="@id/more"
android:visibility="gone" android:visibility="gone"
android:background="?android:actionBarItemBackground" android:background="?android:actionBarItemBackground"
@@ -43,7 +35,6 @@
android:id="@+id/visibility" android:id="@+id/visibility"
android:layout_width="36dp" android:layout_width="36dp"
android:layout_height="36dp" android:layout_height="36dp"
android:layout_marginTop="-5dp"
android:layout_toStartOf="@id/delete_notification" android:layout_toStartOf="@id/delete_notification"
android:background="?android:actionBarItemBackground" android:background="?android:actionBarItemBackground"
android:scaleType="center" android:scaleType="center"
@@ -54,7 +45,6 @@
android:id="@+id/unread_indicator" android:id="@+id/unread_indicator"
android:layout_width="36dp" android:layout_width="36dp"
android:layout_height="36dp" android:layout_height="36dp"
android:layout_marginTop="-5dp"
android:layout_toStartOf="@id/visibility" android:layout_toStartOf="@id/visibility"
android:visibility="gone" android:visibility="gone"
android:tint="?android:colorAccent" android:tint="?android:colorAccent"
@@ -67,14 +57,15 @@
android:layout_height="46sp" android:layout_height="46sp"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_marginEnd="12dp" /> android:layout_marginEnd="12dp"
android:layout_marginTop="5dp" />
<org.joinmastodon.android.ui.views.HeaderSubtitleLinearLayout <org.joinmastodon.android.ui.views.HeaderSubtitleLinearLayout
android:id="@+id/name_wrap" android:id="@+id/name_wrap"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="12dp" android:layout_marginEnd="12dp"
android:layout_marginTop="2sp" android:layout_marginTop="7dp"
android:layout_toStartOf="@id/unread_indicator" android:layout_toStartOf="@id/unread_indicator"
android:layout_toEndOf="@id/avatar" android:layout_toEndOf="@id/avatar"
android:minHeight="24sp"> android:minHeight="24sp">

View File

@@ -19,34 +19,5 @@
android:id="@+id/overflow" android:id="@+id/overflow"
android:title="@string/more_options" android:title="@string/more_options"
android:icon="@drawable/ic_fluent_more_vertical_24_regular" android:icon="@drawable/ic_fluent_more_vertical_24_regular"
android:showAsAction="always"> android:showAsAction="always" />
<menu>
<item
android:id="@+id/settings"
android:icon="@drawable/ic_fluent_settings_24_regular"
android:title="@string/settings" />
<item
android:id="@+id/announcements"
android:icon="@drawable/ic_fluent_megaphone_24_regular"
android:title="@string/sk_announcements" />
<item
android:id="@+id/edit_timelines"
android:icon="@drawable/ic_fluent_edit_24_regular"
android:title="@string/sk_edit_timelines" />
<item
android:id="@+id/lists"
android:icon="@drawable/ic_fluent_people_list_24_regular"
android:title="@string/sk_your_lists"
android:visible="false">
<menu />
</item>
<item
android:id="@+id/hashtags"
android:icon="@drawable/ic_fluent_number_symbol_24_regular"
android:title="@string/sk_hashtags_you_follow"
android:visible="false">
<menu />
</item>
</menu>
</item>
</menu> </menu>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:id="@+id/top">
<item
android:id="@+id/settings"
android:icon="@drawable/ic_fluent_settings_24_regular"
android:title="@string/settings" />
<item
android:id="@+id/announcements"
android:icon="@drawable/ic_fluent_megaphone_24_regular"
android:title="@string/sk_announcements" />
<item
android:id="@+id/edit_timelines"
android:icon="@drawable/ic_fluent_edit_24_regular"
android:title="@string/sk_edit_timelines" />
</group>
<group android:id="@+id/bottom">
<item
android:id="@+id/lists"
android:icon="@drawable/ic_fluent_people_list_24_regular"
android:title="@string/sk_your_lists"
android:visible="false">
<menu />
</item>
<item
android:id="@+id/hashtags"
android:icon="@drawable/ic_fluent_number_symbol_24_regular"
android:title="@string/sk_hashtags_you_follow"
android:visible="false">
<menu />
</item>
</group>
</menu>

View File

@@ -225,12 +225,11 @@
<item name="android:toolbarStyle">@style/Widget.Mastodon.Toolbar</item> <item name="android:toolbarStyle">@style/Widget.Mastodon.Toolbar</item>
<item name="android:textColorPrimary">?colorGray800</item> <item name="android:textColorPrimary">?colorGray800</item>
<item name="android:textColorSecondary">?colorGray800</item> <item name="android:textColorSecondary">?colorGray800</item>
<item name="android:actionOverflowButtonStyle">@style/Theme.Mastodon.ActionButton.Overflow</item> <item name="android:actionOverflowButtonStyle">@style/Widget.Mastodon.ActionButton.Overflow</item>
</style> </style>
<style name="Theme.Mastodon.ActionButton.Overflow" parent="android:Widget.Material.ActionButton.Overflow"> <style name="Widget.Mastodon.ActionButton.Overflow" parent="android:Widget.Material.ActionButton.Overflow">
<item name="android:src">@drawable/ic_fluent_more_vertical_24_regular</item> <item name="android:src">@drawable/ic_fluent_more_vertical_24_regular</item>
<item name="android:paddingEnd">12dp</item>
</style> </style>
<style name="Theme.Mastodon.Toolbar.Dark" parent="android:ThemeOverlay.Material.Dark.ActionBar"> <style name="Theme.Mastodon.Toolbar.Dark" parent="android:ThemeOverlay.Material.Dark.ActionBar">