diff --git a/app/build.gradle b/app/build.gradle index 9c9e85c4..bcaf117d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,8 +12,8 @@ android { applicationId 'org.nuclearfog.twidda' minSdkVersion 21 targetSdkVersion 33 - versionCode 80 - versionName '3.1' + versionCode 81 + versionName '3.1.1' resConfigs 'en', 'de-rDE', 'zh-rCN' } diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/utils/AppStyles.java b/app/src/main/java/org/nuclearfog/twidda/backend/utils/AppStyles.java index 3d4f3518..cda98785 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/utils/AppStyles.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/utils/AppStyles.java @@ -1,18 +1,14 @@ package org.nuclearfog.twidda.backend.utils; -import static android.graphics.Bitmap.Config.ARGB_8888; -import static android.graphics.PorterDuff.Mode.SRC_IN; -import static android.view.View.GONE; - import android.app.Activity; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.Configuration; import android.content.res.Resources; -import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.Point; +import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; @@ -31,17 +27,14 @@ import android.widget.SeekBar; import android.widget.Spinner; import android.widget.TextView; -import androidx.annotation.ArrayRes; import androidx.annotation.ColorInt; import androidx.annotation.Nullable; -import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.widget.Toolbar; import androidx.cardview.widget.CardView; import androidx.core.content.res.ResourcesCompat; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; -import androidx.viewpager.widget.ViewPager; +import androidx.viewpager2.widget.ViewPager2; -import com.google.android.material.tabs.TabLayout; import com.kyleduo.switchbutton.SwitchButton; import org.nuclearfog.twidda.R; @@ -211,7 +204,7 @@ public class AppStyles { public static void setProgressColor(ProgressBar circle, int color) { Drawable icon = circle.getIndeterminateDrawable(); if (icon != null) { - icon.setColorFilter(new PorterDuffColorFilter(color, SRC_IN)); + icon.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)); } } @@ -228,59 +221,6 @@ public class AppStyles { } } - /** - * set tab icons - * - * @param tabLayout Tab layout with tab icons - * @param settings settings to set color - * @param array set of icons - */ - public static void setTabIcons(TabLayout tabLayout, GlobalSettings settings, @ArrayRes int array) { - TextView[] textViews = setTabIconsWithText(tabLayout, settings, array); - for (TextView textView : textViews) { - if (textView != null) { - textView.setVisibility(GONE); - } - } - } - - /** - * create tab icons with TextView - * - * @param tabLayout TabLayout to set the icons - * @param settings settings instance - * @param array Array of drawable resources to set the icons - * @return array of TextViews - */ - public static TextView[] setTabIconsWithText(TabLayout tabLayout, GlobalSettings settings, @ArrayRes int array) { - Context context = tabLayout.getContext(); - TypedArray tArray = context.getResources().obtainTypedArray(array); - TextView[] tabs = new TextView[tabLayout.getTabCount()]; - for (int index = 0; index < tArray.length() && index < tabLayout.getTabCount(); index++) { - TabLayout.Tab mTab = tabLayout.getTabAt(index); - if (mTab != null) { - View tabView; - int resId = tArray.getResourceId(index, 0); - Drawable icon = AppCompatResources.getDrawable(context, resId); - setDrawableColor(icon, settings.getIconColor()); - if (mTab.getCustomView() == null) { - tabView = View.inflate(context, R.layout.item_tab, null); - mTab.setCustomView(tabView); - } else { - // Update existing view - tabView = mTab.getCustomView(); - } - ImageView imageIcon = tabView.findViewById(R.id.tab_icon); - tabs[index] = tabView.findViewById(R.id.tab_text); - tabs[index].setTextColor(settings.getFontColor()); - tabs[index].setTypeface(settings.getTypeFace()); - imageIcon.setImageDrawable(icon); - } - } - tArray.recycle(); - return tabs; - } - /** * setup a transparent blurry toolbar * @@ -292,7 +232,7 @@ public class AppStyles { Drawable backgroundDrawable = background.getDrawable(); if (backgroundDrawable instanceof BitmapDrawable) { try { - Bitmap image = ((BitmapDrawable) backgroundDrawable).getBitmap().copy(ARGB_8888, true); + Bitmap image = ((BitmapDrawable) backgroundDrawable).getBitmap().copy(Bitmap.Config.ARGB_8888, true); // check if image is valid if (image.getWidth() > 1 && image.getHeight() > 1) { // crop image to background size @@ -330,9 +270,9 @@ public class AppStyles { * @param settings global settings instance */ public static void setSeekBarColor(SeekBar seekBar, GlobalSettings settings) { - seekBar.getProgressDrawable().setColorFilter(new PorterDuffColorFilter(settings.getHighlightColor(), SRC_IN)); + seekBar.getProgressDrawable().setColorFilter(new PorterDuffColorFilter(settings.getHighlightColor(), PorterDuff.Mode.SRC_IN)); if (seekBar.getThumb() != null) { - seekBar.getThumb().setColorFilter(new PorterDuffColorFilter(settings.getIconColor(), SRC_IN)); + seekBar.getThumb().setColorFilter(new PorterDuffColorFilter(settings.getIconColor(), PorterDuff.Mode.SRC_IN)); } } @@ -344,7 +284,7 @@ public class AppStyles { */ public static void setDrawableColor(@Nullable Drawable drawable, int color) { if (drawable != null) { - drawable.mutate().setColorFilter(new PorterDuffColorFilter(color, SRC_IN)); + drawable.mutate().setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)); } } @@ -386,10 +326,7 @@ public class AppStyles { private void setSubViewTheme(ViewGroup group) { for (int pos = 0; pos < group.getChildCount(); pos++) { View child = group.getChildAt(pos); - if (child instanceof TabLayout) { - TabLayout tablayout = (TabLayout) child; - tablayout.setSelectedTabIndicatorColor(settings.getHighlightColor()); - } else if (child instanceof SwitchButton) { + if (child instanceof SwitchButton) { SwitchButton sw = (SwitchButton) child; int[] color = {settings.getIconColor()}; sw.setTintColor(settings.getHighlightColor()); @@ -403,28 +340,28 @@ public class AppStyles { } else if (child instanceof TextView) { TextView tv = (TextView) child; tv.setTypeface(settings.getTypeFace()); - tv.setTextColor(settings.getFontColor()); + tv.setTextColor(settings.getTextColor()); setDrawableColor(tv, settings.getIconColor()); if (child instanceof Button) { Button btn = (Button) child; - setButtonColor(btn, settings.getFontColor()); + setButtonColor(btn, settings.getTextColor()); } else if (child instanceof EditText) { EditText edit = (EditText) child; - edit.setHintTextColor(settings.getFontColor() & HINT_TRANSPARENCY); + edit.setHintTextColor(settings.getTextColor() & HINT_TRANSPARENCY); } } else if (child instanceof ImageView) { ImageView img = (ImageView) child; setDrawableColor(img.getDrawable(), settings.getIconColor()); if (child instanceof ImageButton) { ImageButton btn = (ImageButton) child; - setButtonColor(btn, settings.getFontColor()); + setButtonColor(btn, settings.getTextColor()); } } else if (child instanceof ViewGroup) { if (child instanceof CardView) { CardView card = (CardView) child; card.setCardBackgroundColor(settings.getCardColor()); setSubViewTheme(card); - } else if (!(child instanceof ViewPager)) { + } else if (!(child instanceof ViewPager2)) { setSubViewTheme((ViewGroup) child); } } diff --git a/app/src/main/java/org/nuclearfog/twidda/config/Configuration.java b/app/src/main/java/org/nuclearfog/twidda/config/Configuration.java index ac43737b..bec4413c 100644 --- a/app/src/main/java/org/nuclearfog/twidda/config/Configuration.java +++ b/app/src/main/java/org/nuclearfog/twidda/config/Configuration.java @@ -1,5 +1,8 @@ package org.nuclearfog.twidda.config; +import androidx.annotation.ArrayRes; + +import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.model.Account; /** @@ -41,6 +44,7 @@ public enum Configuration { private final boolean statusSpoilerSupported; private final boolean statusVisibilitySupported; private final boolean directMessageSupported; + private final int arrayResHome; /** * @param accountType account login type, see {@link Account} @@ -61,6 +65,7 @@ public enum Configuration { statusSpoilerSupported = false; statusVisibilitySupported = false; directMessageSupported = true; + arrayResHome = R.array.home_twitter_icons; break; default: @@ -76,6 +81,7 @@ public enum Configuration { statusSpoilerSupported = true; statusVisibilitySupported = true; directMessageSupported = false; + arrayResHome = R.array.home_mastodon_icons; break; } } @@ -163,4 +169,14 @@ public enum Configuration { public boolean directmessageSupported() { return directMessageSupported; } + + /** + * get home tabitems drawable IDs + * + * @return Integer array resource containing drawable IDs + */ + @ArrayRes + public int getHomeTabIcons() { + return arrayResHome; + } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/config/GlobalSettings.java b/app/src/main/java/org/nuclearfog/twidda/config/GlobalSettings.java index 773cdf22..f16ffb68 100644 --- a/app/src/main/java/org/nuclearfog/twidda/config/GlobalSettings.java +++ b/app/src/main/java/org/nuclearfog/twidda/config/GlobalSettings.java @@ -210,7 +210,7 @@ public class GlobalSettings { * * @return font color value */ - public int getFontColor() { + public int getTextColor() { return font_color; } @@ -219,7 +219,7 @@ public class GlobalSettings { * * @param color font color value */ - public void setFontColor(int color) { + public void setTextColor(int color) { font_color = color; Editor edit = settings.edit(); diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/MainActivity.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/MainActivity.java index da2465af..fcaa6017 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/activities/MainActivity.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/MainActivity.java @@ -23,17 +23,15 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.SearchView.OnQueryTextListener; import androidx.appcompat.widget.Toolbar; -import androidx.viewpager.widget.ViewPager; - -import com.google.android.material.tabs.TabLayout; -import com.google.android.material.tabs.TabLayout.OnTabSelectedListener; -import com.google.android.material.tabs.TabLayout.Tab; +import androidx.viewpager2.widget.ViewPager2; import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.backend.utils.AppStyles; import org.nuclearfog.twidda.config.GlobalSettings; import org.nuclearfog.twidda.ui.adapter.FragmentAdapter; import org.nuclearfog.twidda.ui.dialogs.ProgressDialog; +import org.nuclearfog.twidda.ui.views.TabSelector; +import org.nuclearfog.twidda.ui.views.TabSelector.OnTabSelectedListener; /** * Main Activity of the App @@ -49,8 +47,8 @@ public class MainActivity extends AppCompatActivity implements ActivityResultCal private Intent loginIntent; private Dialog loadingCircle; - private TabLayout tabLayout; - private ViewPager pager; + private TabSelector tabSelector; + private ViewPager2 viewPager; private Toolbar toolbar; private ViewGroup root; @@ -66,23 +64,23 @@ public class MainActivity extends AppCompatActivity implements ActivityResultCal super.onCreate(savedInstanceState); setContentView(R.layout.page_main); toolbar = findViewById(R.id.home_toolbar); - pager = findViewById(R.id.home_pager); - tabLayout = findViewById(R.id.home_tab); + viewPager = findViewById(R.id.home_pager); + tabSelector = findViewById(R.id.home_tab); root = findViewById(R.id.main_layout); loadingCircle = new ProgressDialog(this); settings = GlobalSettings.getInstance(this); - tabLayout.setupWithViewPager(pager); - pager.setOffscreenPageLimit(4); - adapter = new FragmentAdapter(this, getSupportFragmentManager()); - pager.setAdapter(adapter); + tabSelector.addViewPager(viewPager); + viewPager.setOffscreenPageLimit(4); + adapter = new FragmentAdapter(this); + viewPager.setAdapter(adapter); AppStyles.setTheme(root); AppStyles.setOverflowIcon(toolbar, settings.getIconColor()); toolbar.setTitle(""); setSupportActionBar(toolbar); - tabLayout.addOnTabSelectedListener(this); + tabSelector.addOnTabSelectedListener(this); } @@ -123,7 +121,7 @@ public class MainActivity extends AppCompatActivity implements ActivityResultCal case SettingsActivity.RETURN_APP_LOGOUT: adapter.clear(); - pager.setAdapter(adapter); + viewPager.setAdapter(adapter); loginIntent = new Intent(this, LoginActivity.class); activityResultLauncher.launch(loginIntent); break; @@ -200,8 +198,8 @@ public class MainActivity extends AppCompatActivity implements ActivityResultCal @Override public void onBackPressed() { - if (tabLayout.getSelectedTabPosition() > 0) { - pager.setCurrentItem(0); + if (viewPager.getCurrentItem() > 0) { + viewPager.setCurrentItem(0); } else { super.onBackPressed(); } @@ -228,19 +226,8 @@ public class MainActivity extends AppCompatActivity implements ActivityResultCal @Override - public void onTabSelected(Tab tab) { - } - - - @Override - public void onTabUnselected(Tab tab) { - adapter.scrollToTop(tab.getPosition()); - } - - - @Override - public void onTabReselected(Tab tab) { - adapter.scrollToTop(tab.getPosition()); + public void onTabSelected(int oldPosition, int position) { + adapter.scrollToTop(oldPosition); } /** @@ -250,15 +237,6 @@ public class MainActivity extends AppCompatActivity implements ActivityResultCal AppStyles.setTheme(root); AppStyles.setOverflowIcon(toolbar, settings.getIconColor()); adapter.setupForHomePage(); - switch (settings.getLogin().getConfiguration()) { - case TWITTER1: - case TWITTER2: - AppStyles.setTabIcons(tabLayout, settings, R.array.home_twitter_icons); - break; - - case MASTODON: - AppStyles.setTabIcons(tabLayout, settings, R.array.home_mastodon_icons); - break; - } + tabSelector.addTabIcons(settings.getLogin().getConfiguration().getHomeTabIcons()); } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/ProfileActivity.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/ProfileActivity.java index b8991090..23db35be 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/activities/ProfileActivity.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/ProfileActivity.java @@ -46,11 +46,8 @@ import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.ConstraintSet; import androidx.core.widget.NestedScrollView; import androidx.core.widget.NestedScrollView.OnScrollChangeListener; -import androidx.viewpager.widget.ViewPager; +import androidx.viewpager2.widget.ViewPager2; -import com.google.android.material.tabs.TabLayout; -import com.google.android.material.tabs.TabLayout.OnTabSelectedListener; -import com.google.android.material.tabs.TabLayout.Tab; import com.squareup.picasso.Callback; import com.squareup.picasso.Picasso; import com.squareup.picasso.Transformation; @@ -83,6 +80,8 @@ import org.nuclearfog.twidda.ui.dialogs.ConfirmDialog; import org.nuclearfog.twidda.ui.dialogs.ConfirmDialog.OnConfirmListener; import org.nuclearfog.twidda.ui.views.LockableLinearLayout; import org.nuclearfog.twidda.ui.views.LockableLinearLayout.LockCallback; +import org.nuclearfog.twidda.ui.views.TabSelector; +import org.nuclearfog.twidda.ui.views.TabSelector.OnTabSelectedListener; import java.text.SimpleDateFormat; import java.util.List; @@ -159,12 +158,11 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult private NestedScrollView root; private ConstraintLayout header; private LockableLinearLayout body; - private TextView[] tabIndicator; private TextView user_location, user_createdAt, user_website, description, follow_back, username, screenName; private ImageView profileImage, bannerImage, toolbarBackground; private Button following, follower; - private ViewPager tabPages; - private TabLayout tabLayout; + private ViewPager2 viewPager; + private TabSelector tabSelector; private Toolbar toolbar; @Nullable @@ -200,8 +198,8 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult user_location = findViewById(R.id.location); user_createdAt = findViewById(R.id.profile_date); follow_back = findViewById(R.id.follow_back); - tabLayout = findViewById(R.id.profile_tab); - tabPages = findViewById(R.id.profile_pager); + tabSelector = findViewById(R.id.profile_tab); + viewPager = findViewById(R.id.profile_pager); relationLoader = new RelationLoader(this); userLoader = new UserLoader(this); @@ -227,14 +225,14 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult description.setLinkTextColor(settings.getHighlightColor()); AppStyles.setTheme(root); user_website.setTextColor(settings.getHighlightColor()); - tabLayout.setBackgroundColor(Color.TRANSPARENT); + tabSelector.setBackgroundColor(Color.TRANSPARENT); toolbar.setTitle(""); setSupportActionBar(toolbar); - adapter = new FragmentAdapter(this, getSupportFragmentManager()); - tabPages.setAdapter(adapter); - tabPages.setOffscreenPageLimit(3); - tabLayout.setupWithViewPager(tabPages); + adapter = new FragmentAdapter(this); + viewPager.setAdapter(adapter); + viewPager.setOffscreenPageLimit(3); + tabSelector.addViewPager(viewPager); confirmDialog = new ConfirmDialog(this); // get parameters @@ -251,9 +249,9 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult } adapter.setupProfilePage(userId); if (settings.likeEnabled()) { - tabIndicator = AppStyles.setTabIconsWithText(tabLayout, settings, R.array.profile_tab_icons_like); + tabSelector.addTabIcons(R.array.profile_tab_icons_like); } else { - tabIndicator = AppStyles.setTabIconsWithText(tabLayout, settings, R.array.profile_tab_icons); + tabSelector.addTabIcons(R.array.profile_tab_icons); } if (user != null) { setUser(user); @@ -267,7 +265,7 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult RelationParam param = new RelationParam(userId, RelationParam.LOAD); relationLoader.execute(param, relationCallback); } - tabLayout.addOnTabSelectedListener(this); + tabSelector.addOnTabSelectedListener(this); following.setOnClickListener(this); follower.setOnClickListener(this); profileImage.setOnClickListener(this); @@ -480,8 +478,8 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult @Override public void onBackPressed() { - if (tabLayout.getSelectedTabPosition() > 0) { - tabPages.setCurrentItem(0); + if (viewPager.getCurrentItem() > 0) { + viewPager.setCurrentItem(0); } else { Intent returnData = new Intent(); returnData.putExtra(KEY_USER_UPDATE, user); @@ -618,19 +616,8 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult @Override - public void onTabSelected(Tab tab) { - } - - - @Override - public void onTabUnselected(Tab tab) { - adapter.scrollToTop(tab.getPosition()); - } - - - @Override - public void onTabReselected(Tab tab) { - adapter.scrollToTop(tab.getPosition()); + public void onTabSelected(int oldPosition, int position) { + adapter.scrollToTop(oldPosition); } @@ -747,16 +734,14 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult username.setText(user.getUsername()); screenName.setText(user.getScreenname()); if (user.getStatusCount() >= 0) { - tabIndicator[0].setText(StringUtils.NUMBER_FORMAT.format(user.getStatusCount())); + tabSelector.setLabel(0, StringUtils.NUMBER_FORMAT.format(user.getStatusCount())); } else { - tabIndicator[0].setText(""); + tabSelector.setLabel(0, ""); } - if (tabIndicator.length > 1) { - if (user.getFavoriteCount() >= 0) { - tabIndicator[1].setText(StringUtils.NUMBER_FORMAT.format(user.getFavoriteCount())); - } else { - tabIndicator[1].setText(""); - } + if (user.getFavoriteCount() >= 0) { + tabSelector.setLabel(1, StringUtils.NUMBER_FORMAT.format(user.getFavoriteCount())); + } else { + tabSelector.setLabel(1, ""); } if (user_createdAt.getVisibility() != VISIBLE) { String date = SimpleDateFormat.getDateTimeInstance().format(user.getTimestamp()); diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/SearchActivity.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/SearchActivity.java index 9a3acbe2..708232c7 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/activities/SearchActivity.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/SearchActivity.java @@ -17,17 +17,15 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.SearchView.OnQueryTextListener; import androidx.appcompat.widget.Toolbar; -import androidx.viewpager.widget.ViewPager; - -import com.google.android.material.tabs.TabLayout; -import com.google.android.material.tabs.TabLayout.OnTabSelectedListener; -import com.google.android.material.tabs.TabLayout.Tab; +import androidx.viewpager2.widget.ViewPager2; import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.backend.utils.AppStyles; import org.nuclearfog.twidda.config.Configuration; import org.nuclearfog.twidda.config.GlobalSettings; import org.nuclearfog.twidda.ui.adapter.FragmentAdapter; +import org.nuclearfog.twidda.ui.views.TabSelector; +import org.nuclearfog.twidda.ui.views.TabSelector.OnTabSelectedListener; /** * search Activity for statuses and users @@ -46,8 +44,7 @@ public class SearchActivity extends AppCompatActivity implements OnTabSelectedLi private FragmentAdapter adapter; private GlobalSettings settings; - private TabLayout tabLayout; - private ViewPager pager; + private ViewPager2 viewPager; private Toolbar toolbar; private String search = ""; @@ -64,26 +61,26 @@ public class SearchActivity extends AppCompatActivity implements OnTabSelectedLi super.onCreate(b); setContentView(R.layout.page_search); ViewGroup root = findViewById(R.id.search_layout); + TabSelector tabSelector = findViewById(R.id.search_tab); toolbar = findViewById(R.id.search_toolbar); - tabLayout = findViewById(R.id.search_tab); - pager = findViewById(R.id.search_pager); + viewPager = findViewById(R.id.search_pager); toolbar.setTitle(""); setSupportActionBar(toolbar); settings = GlobalSettings.getInstance(this); - adapter = new FragmentAdapter(this, getSupportFragmentManager()); - tabLayout.setupWithViewPager(pager); - tabLayout.addOnTabSelectedListener(this); - pager.setAdapter(adapter); - pager.setOffscreenPageLimit(2); + adapter = new FragmentAdapter(this); + tabSelector.addViewPager(viewPager); + tabSelector.addOnTabSelectedListener(this); + viewPager.setAdapter(adapter); + viewPager.setOffscreenPageLimit(2); String search = getIntent().getStringExtra(KEY_SEARCH_QUERY); if (search != null) { this.search = search; boolean enableHashtags = !search.startsWith("#") && settings.getLogin().getConfiguration() == Configuration.MASTODON; adapter.setupSearchPage(search, enableHashtags); - AppStyles.setTabIcons(tabLayout, settings, R.array.search_tab_icons); + tabSelector.addTabIcons(R.array.search_tab_icons); } AppStyles.setTheme(root); } @@ -91,8 +88,8 @@ public class SearchActivity extends AppCompatActivity implements OnTabSelectedLi @Override public void onBackPressed() { - if (tabLayout.getSelectedTabPosition() > 0) { - pager.setCurrentItem(0); + if (viewPager.getCurrentItem() > 0) { + viewPager.setCurrentItem(0); } else { super.onBackPressed(); } @@ -162,19 +159,8 @@ public class SearchActivity extends AppCompatActivity implements OnTabSelectedLi @Override - public void onTabSelected(Tab tab) { + public void onTabSelected(int oldPosition, int position) { invalidateOptionsMenu(); - } - - - @Override - public void onTabUnselected(Tab tab) { - adapter.scrollToTop(tab.getPosition()); - } - - - @Override - public void onTabReselected(Tab tab) { - adapter.scrollToTop(tab.getPosition()); + adapter.scrollToTop(oldPosition); } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/SettingsActivity.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/SettingsActivity.java index 380dbf1c..f39b93c8 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/activities/SettingsActivity.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/SettingsActivity.java @@ -348,7 +348,7 @@ public class SettingsActivity extends AppCompatActivity implements OnClickListen // set font color else if (v.getId() == R.id.color_text) { mode = COLOR_TEXT; - color = settings.getFontColor(); + color = settings.getTextColor(); showColorPicker(color, false); } // set popup color @@ -418,7 +418,7 @@ public class SettingsActivity extends AppCompatActivity implements OnClickListen break; case COLOR_TEXT: - settings.setFontColor(color); + settings.setTextColor(color); fontAdapter.notifyDataSetChanged(); scaleAdapter.notifyDataSetChanged(); if (settings.isLoggedIn()) { diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/UserlistActivity.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/UserlistActivity.java index 56acca99..6185616e 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/activities/UserlistActivity.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/UserlistActivity.java @@ -22,11 +22,7 @@ import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.SearchView.OnQueryTextListener; import androidx.appcompat.widget.Toolbar; import androidx.fragment.app.Fragment; -import androidx.viewpager.widget.ViewPager; - -import com.google.android.material.tabs.TabLayout; -import com.google.android.material.tabs.TabLayout.OnTabSelectedListener; -import com.google.android.material.tabs.TabLayout.Tab; +import androidx.viewpager2.widget.ViewPager2; import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.backend.api.ConnectionException; @@ -46,6 +42,8 @@ import org.nuclearfog.twidda.ui.adapter.FragmentAdapter; import org.nuclearfog.twidda.ui.dialogs.ConfirmDialog; import org.nuclearfog.twidda.ui.dialogs.ConfirmDialog.OnConfirmListener; import org.nuclearfog.twidda.ui.fragments.UserFragment; +import org.nuclearfog.twidda.ui.views.TabSelector; +import org.nuclearfog.twidda.ui.views.TabSelector.OnTabSelectedListener; import java.util.regex.Pattern; @@ -111,8 +109,7 @@ public class UserlistActivity extends AppCompatActivity implements ActivityResul private ConfirmDialog confirmDialog; - private TabLayout tablayout; - private ViewPager pager; + private ViewPager2 viewPager; private Toolbar toolbar; @Nullable @@ -132,17 +129,17 @@ public class UserlistActivity extends AppCompatActivity implements ActivityResul super.onCreate(b); setContentView(R.layout.page_listdetail); ViewGroup root = findViewById(R.id.listdetail_root); + TabSelector tabSelector = findViewById(R.id.listdetail_tab); toolbar = findViewById(R.id.listdetail_toolbar); - tablayout = findViewById(R.id.listdetail_tab); - pager = findViewById(R.id.listdetail_pager); + viewPager = findViewById(R.id.listdetail_pager); confirmDialog = new ConfirmDialog(this); listLoaderAsync = new ListAction(this); listManagerAsync = new ListManager(this); - adapter = new FragmentAdapter(this, getSupportFragmentManager()); - pager.setOffscreenPageLimit(3); - pager.setAdapter(adapter); - tablayout.setupWithViewPager(pager); + adapter = new FragmentAdapter(this); + viewPager.setOffscreenPageLimit(3); + viewPager.setAdapter(adapter); + tabSelector.addViewPager(viewPager); settings = GlobalSettings.getInstance(this); Object data = getIntent().getSerializableExtra(KEY_LIST_DATA); @@ -155,10 +152,10 @@ public class UserlistActivity extends AppCompatActivity implements ActivityResul setSupportActionBar(toolbar); AppStyles.setTheme(root); - AppStyles.setTabIcons(tablayout, settings, R.array.list_tab_icons); + tabSelector.addTabIcons(R.array.list_tab_icons); confirmDialog.setConfirmListener(this); - tablayout.addOnTabSelectedListener(this); + tabSelector.addOnTabSelectedListener(this); } @@ -254,8 +251,8 @@ public class UserlistActivity extends AppCompatActivity implements ActivityResul @Override public void onBackPressed() { - if (tablayout.getSelectedTabPosition() > 0) { - pager.setCurrentItem(0); + if (viewPager.getCurrentItem() > 0) { + viewPager.setCurrentItem(0); } else { Intent result = new Intent(); result.putExtra(RESULT_UPDATE_LIST, userList); @@ -308,19 +305,8 @@ public class UserlistActivity extends AppCompatActivity implements ActivityResul @Override - public void onTabSelected(Tab tab) { - } - - - @Override - public void onTabUnselected(Tab tab) { - adapter.scrollToTop(tab.getPosition()); - } - - - @Override - public void onTabReselected(Tab tab) { - adapter.scrollToTop(tab.getPosition()); + public void onTabSelected(int oldPosition, int position) { + adapter.scrollToTop(oldPosition); } diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/UserlistsActivity.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/UserlistsActivity.java index 90eb1e60..c75569ef 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/activities/UserlistsActivity.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/UserlistsActivity.java @@ -18,16 +18,14 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; -import androidx.viewpager.widget.ViewPager; - -import com.google.android.material.tabs.TabLayout; -import com.google.android.material.tabs.TabLayout.OnTabSelectedListener; -import com.google.android.material.tabs.TabLayout.Tab; +import androidx.viewpager2.widget.ViewPager2; import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.backend.utils.AppStyles; import org.nuclearfog.twidda.config.GlobalSettings; import org.nuclearfog.twidda.ui.adapter.FragmentAdapter; +import org.nuclearfog.twidda.ui.views.TabSelector; +import org.nuclearfog.twidda.ui.views.TabSelector.OnTabSelectedListener; /** * Activity to show userlists of an user @@ -47,8 +45,7 @@ public class UserlistsActivity extends AppCompatActivity implements ActivityResu private FragmentAdapter adapter; private GlobalSettings settings; - private ViewPager pager; - private TabLayout tabLayout; + private ViewPager2 viewPager; private boolean isHome = false; @@ -65,25 +62,25 @@ public class UserlistsActivity extends AppCompatActivity implements ActivityResu setContentView(R.layout.page_list); ViewGroup root = findViewById(R.id.list_view); Toolbar toolbar = findViewById(R.id.list_toolbar); - pager = findViewById(R.id.list_pager); - tabLayout = findViewById(R.id.list_tab); + TabSelector tabSelector = findViewById(R.id.list_tab); + viewPager = findViewById(R.id.list_pager); toolbar.setTitle(R.string.list_appbar); setSupportActionBar(toolbar); - adapter = new FragmentAdapter(this, getSupportFragmentManager()); + adapter = new FragmentAdapter(this); settings = GlobalSettings.getInstance(this); AppStyles.setTheme(root); - pager.setAdapter(adapter); - pager.setOffscreenPageLimit(2); - tabLayout.setupWithViewPager(pager); - tabLayout.addOnTabSelectedListener(this); + viewPager.setAdapter(adapter); + viewPager.setOffscreenPageLimit(2); + tabSelector.addViewPager(viewPager); + tabSelector.addOnTabSelectedListener(this); long ownerId = getIntent().getLongExtra(KEY_USERLIST_OWNER_ID, 0L); isHome = ownerId == settings.getLogin().getId(); adapter.setupListPage(ownerId); - AppStyles.setTabIcons(tabLayout, settings, R.array.userlist_tab_icons); + tabSelector.addTabIcons(R.array.userlist_tab_icons); AppStyles.setOverflowIcon(toolbar, settings.getIconColor()); } @@ -98,8 +95,8 @@ public class UserlistsActivity extends AppCompatActivity implements ActivityResu @Override public void onBackPressed() { - if (tabLayout.getSelectedTabPosition() > 0) { - pager.setCurrentItem(0); + if (viewPager.getCurrentItem() > 0) { + viewPager.setCurrentItem(0); } else { super.onBackPressed(); } @@ -134,18 +131,7 @@ public class UserlistsActivity extends AppCompatActivity implements ActivityResu @Override - public void onTabSelected(Tab tab) { - } - - - @Override - public void onTabUnselected(Tab tab) { - adapter.scrollToTop(tab.getPosition()); - } - - - @Override - public void onTabReselected(Tab tab) { - adapter.scrollToTop(tab.getPosition()); + public void onTabSelected(int oldPosition, int position) { + adapter.scrollToTop(oldPosition); } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/UsersActivity.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/UsersActivity.java index b55e5c92..1808b010 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/activities/UsersActivity.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/UsersActivity.java @@ -14,11 +14,7 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.SearchView.OnQueryTextListener; import androidx.appcompat.widget.Toolbar; -import androidx.viewpager.widget.ViewPager; - -import com.google.android.material.tabs.TabLayout; -import com.google.android.material.tabs.TabLayout.OnTabSelectedListener; -import com.google.android.material.tabs.TabLayout.Tab; +import androidx.viewpager2.widget.ViewPager2; import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.backend.async.AsyncExecutor.AsyncCallback; @@ -29,6 +25,8 @@ import org.nuclearfog.twidda.backend.utils.AppStyles; import org.nuclearfog.twidda.backend.utils.ErrorHandler; import org.nuclearfog.twidda.config.GlobalSettings; import org.nuclearfog.twidda.ui.adapter.FragmentAdapter; +import org.nuclearfog.twidda.ui.views.TabSelector; +import org.nuclearfog.twidda.ui.views.TabSelector.OnTabSelectedListener; import java.util.regex.Pattern; @@ -103,8 +101,8 @@ public class UsersActivity extends AppCompatActivity implements OnTabSelectedLis private FragmentAdapter adapter; private Toolbar toolbar; - private TabLayout tablayout; - private ViewPager pager; + private TabSelector tabSelector; + private ViewPager2 viewPager; private int mode; @@ -121,13 +119,13 @@ public class UsersActivity extends AppCompatActivity implements OnTabSelectedLis setContentView(R.layout.page_exclude); ViewGroup root = findViewById(R.id.page_exclude_root); toolbar = findViewById(R.id.page_exclude_toolbar); - tablayout = findViewById(R.id.page_exclude_tab); - pager = findViewById(R.id.page_exclude_pager); + tabSelector = findViewById(R.id.page_exclude_tab); + viewPager = findViewById(R.id.page_exclude_pager); filterAsync = new FilterLoader(this); settings = GlobalSettings.getInstance(this); - adapter = new FragmentAdapter(this, getSupportFragmentManager()); - pager.setAdapter(adapter); + adapter = new FragmentAdapter(this); + //pager.setAdapter(adapter); mode = getIntent().getIntExtra(KEY_USERS_MODE, 0); long id = getIntent().getLongExtra(KEY_USERS_ID, 0L); @@ -135,48 +133,48 @@ public class UsersActivity extends AppCompatActivity implements OnTabSelectedLis switch (mode) { case USERS_FRIENDS: adapter.setupFollowingPage(id); - pager.setOffscreenPageLimit(1); - tablayout.setVisibility(View.GONE); + viewPager.setOffscreenPageLimit(1); + tabSelector.setVisibility(View.GONE); toolbar.setTitle(R.string.userlist_following); break; case USERS_FOLLOWER: adapter.setupFollowerPage(id); - pager.setOffscreenPageLimit(1); - tablayout.setVisibility(View.GONE); + viewPager.setOffscreenPageLimit(1); + tabSelector.setVisibility(View.GONE); toolbar.setTitle(R.string.userlist_follower); break; case USERS_REPOST: adapter.setupReposterPage(id); - pager.setOffscreenPageLimit(1); - tablayout.setVisibility(View.GONE); + viewPager.setOffscreenPageLimit(1); + tabSelector.setVisibility(View.GONE); toolbar.setTitle(R.string.toolbar_userlist_repost); break; case USERS_FAVORIT: int title = settings.likeEnabled() ? R.string.toolbar_status_liker : R.string.toolbar_status_favoriter; adapter.setFavoriterPage(id); - pager.setOffscreenPageLimit(1); - tablayout.setVisibility(View.GONE); + viewPager.setOffscreenPageLimit(1); + tabSelector.setVisibility(View.GONE); toolbar.setTitle(title); break; case USERS_EXCLUDED: adapter.setupMuteBlockPage(); - pager.setOffscreenPageLimit(2); - tablayout.setupWithViewPager(pager); - tablayout.addOnTabSelectedListener(this); - AppStyles.setTabIcons(tablayout, settings, R.array.user_exclude_icons); + viewPager.setOffscreenPageLimit(2); + tabSelector.addViewPager(viewPager); + tabSelector.addOnTabSelectedListener(this); + tabSelector.addTabIcons(R.array.user_exclude_icons); toolbar.setTitle(R.string.menu_toolbar_excluded_users); break; case USERS_REQUESTS: adapter.setupFollowRequestPage(); - pager.setOffscreenPageLimit(2); - tablayout.setupWithViewPager(pager); - tablayout.addOnTabSelectedListener(this); - AppStyles.setTabIcons(tablayout, settings, R.array.user_requests_icon); + viewPager.setOffscreenPageLimit(2); + tabSelector.addViewPager(viewPager); + tabSelector.addOnTabSelectedListener(this); + tabSelector.addTabIcons(R.array.user_requests_icon); toolbar.setTitle(R.string.menu_toolbar_request); break; } @@ -187,8 +185,8 @@ public class UsersActivity extends AppCompatActivity implements OnTabSelectedLis @Override public void onBackPressed() { - if (tablayout.getVisibility() == View.VISIBLE && tablayout.getSelectedTabPosition() > 0) { - pager.setCurrentItem(0); + if (tabSelector.getVisibility() == View.VISIBLE && viewPager.getCurrentItem() > 0) { + viewPager.setCurrentItem(0); } else { super.onBackPressed(); } @@ -217,10 +215,10 @@ public class UsersActivity extends AppCompatActivity implements OnTabSelectedLis public boolean onPrepareOptionsMenu(Menu m) { if (mode == USERS_EXCLUDED) { SearchView searchView = (SearchView) m.findItem(R.id.menu_exclude_user).getActionView(); - if (tablayout.getSelectedTabPosition() == 0) { + if (viewPager.getCurrentItem() == 0) { String hint = getString(R.string.menu_hint_mute_user); searchView.setQueryHint(hint); - } else if (tablayout.getSelectedTabPosition() == 1) { + } else if (viewPager.getCurrentItem() == 1) { String hint = getString(R.string.menu_hint_block_user); searchView.setQueryHint(hint); } @@ -244,32 +242,21 @@ public class UsersActivity extends AppCompatActivity implements OnTabSelectedLis @Override - public void onTabSelected(Tab tab) { + public void onTabSelected(int oldPosition, int position) { + adapter.scrollToTop(oldPosition); // reset menu invalidateOptionsMenu(); } - @Override - public void onTabUnselected(Tab tab) { - adapter.scrollToTop(tab.getPosition()); - } - - - @Override - public void onTabReselected(Tab tab) { - adapter.scrollToTop(tab.getPosition()); - } - - @Override public boolean onQueryTextSubmit(String query) { if (USERNAME_PATTERN.matcher(query).matches()) { if (filterAsync.isIdle()) { - if (tablayout.getSelectedTabPosition() == 0) { + if (viewPager.getCurrentItem() == 0) { FilterParam param = new FilterParam(FilterParam.MUTE, query); filterAsync.execute(param, this); - } else if (tablayout.getSelectedTabPosition() == 1) { + } else if (viewPager.getCurrentItem() == 1) { FilterParam param = new FilterParam(FilterParam.BLOCK, query); filterAsync.execute(param, this); } diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/FontAdapter.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/FontAdapter.java index fb436368..cb42f82e 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/FontAdapter.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/FontAdapter.java @@ -60,7 +60,7 @@ public class FontAdapter extends BaseAdapter { textItem = view.findViewById(R.id.dropdown_textitem); textItem.setText(FONT_NAMES[pos]); textItem.setTypeface(FONT_TYPES[pos]); - textItem.setTextColor(settings.getFontColor()); + textItem.setTextColor(settings.getTextColor()); textItem.setBackgroundColor(settings.getCardColor()); view.setBackgroundColor(settings.getBackgroundColor()); return view; diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/FragmentAdapter.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/FragmentAdapter.java index 33b8d61b..502bbf33 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/FragmentAdapter.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/FragmentAdapter.java @@ -31,13 +31,12 @@ import static org.nuclearfog.twidda.ui.fragments.UserListFragment.KEY_FRAG_LIST_ import static org.nuclearfog.twidda.ui.fragments.UserListFragment.LIST_USER_OWNS; import static org.nuclearfog.twidda.ui.fragments.UserListFragment.LIST_USER_SUBSCR_TO; -import android.content.Context; import android.os.Bundle; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentStatePagerAdapter; +import androidx.fragment.app.FragmentActivity; +import androidx.viewpager2.adapter.FragmentStateAdapter; import org.nuclearfog.twidda.config.GlobalSettings; import org.nuclearfog.twidda.model.Account; @@ -50,36 +49,49 @@ import org.nuclearfog.twidda.ui.fragments.UserFragment; import org.nuclearfog.twidda.ui.fragments.UserListFragment; /** - * custom adapter used for {@link androidx.viewpager.widget.ViewPager} + * custom adapter used for {@link androidx.viewpager2.widget.ViewPager2} * * @author nuclearfog */ -public class FragmentAdapter extends FragmentStatePagerAdapter { +public class FragmentAdapter extends FragmentStateAdapter { private ListFragment[] fragments = {}; private GlobalSettings settings; /** - * @param fManager Activity Fragment Manager + * @param fragmentActivity fragment activity */ - public FragmentAdapter(Context context, FragmentManager fManager) { - super(fManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); - settings = GlobalSettings.getInstance(context); + public FragmentAdapter(FragmentActivity fragmentActivity) { + super(fragmentActivity); + settings = GlobalSettings.getInstance(fragmentActivity.getApplicationContext()); } - @Override @NonNull - public Fragment getItem(int index) { - return fragments[index]; + @Override + public Fragment createFragment(int position) { + return fragments[position]; } @Override - public int getCount() { + public int getItemCount() { return fragments.length; } + /** + * get fragment at index + * + * @param index index of the fragment + * @return fragment + */ + public ListFragment getItem(int index) { + if (index >= 0 && index < fragments.length) { + return fragments[index]; + } + return null; + } + /** * Check if adapter is empty * diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/LocationAdapter.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/LocationAdapter.java index d48c1da4..97a4c84a 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/LocationAdapter.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/LocationAdapter.java @@ -63,7 +63,7 @@ public class LocationAdapter extends BaseAdapter { } textItem = view.findViewById(R.id.dropdown_textitem); textItem.setBackgroundColor(settings.getCardColor()); - textItem.setTextColor(settings.getFontColor()); + textItem.setTextColor(settings.getTextColor()); textItem.setTypeface(settings.getTypeFace()); textItem.setText(locations.get(pos).getFullName()); view.setBackgroundColor(settings.getBackgroundColor()); diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/NetworkAdapter.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/NetworkAdapter.java index 5dbb638a..a149fedb 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/NetworkAdapter.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/NetworkAdapter.java @@ -81,7 +81,7 @@ public class NetworkAdapter extends BaseAdapter { textItem = convertView.findViewById(R.id.dropdown_textitem); textItem.setText(STRINGS[position]); textItem.setCompoundDrawablesWithIntrinsicBounds(ICONS[position], 0, 0, 0); - textItem.setTextColor(settings.getFontColor()); + textItem.setTextColor(settings.getTextColor()); textItem.setBackgroundColor(settings.getCardColor()); AppStyles.setDrawableColor(textItem, settings.getIconColor()); convertView.setBackgroundColor(settings.getBackgroundColor()); diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/ScaleAdapter.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/ScaleAdapter.java index 15a49085..b1a29059 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/ScaleAdapter.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/ScaleAdapter.java @@ -58,7 +58,7 @@ public class ScaleAdapter extends BaseAdapter { textItem = view.findViewById(R.id.dropdown_textitem); textItem.setText(String.format(Locale.getDefault(), "%.1f X", FONT_SCALES[pos])); textItem.setTypeface(settings.getTypeFace()); - textItem.setTextColor(settings.getFontColor()); + textItem.setTextColor(settings.getTextColor()); textItem.setBackgroundColor(settings.getCardColor()); view.setBackgroundColor(settings.getBackgroundColor()); return view; diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/CardHolder.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/CardHolder.java index d4a2e51c..b61a3366 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/CardHolder.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/CardHolder.java @@ -63,7 +63,7 @@ public class CardHolder extends ViewHolder implements OnClickListener { itemView.getLayoutParams().width = parent.getMeasuredHeight() * 16 / 9; linkText.setTypeface(settings.getTypeFace()); - linkText.setTextColor(settings.getFontColor()); + linkText.setTextColor(settings.getTextColor()); linkText.setBackgroundColor(settings.getBackgroundColor() & TEXT_TRANSPARENCY); linkText.setOnClickListener(this); diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/Optionholder.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/Optionholder.java index 76d8e7f7..06868156 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/Optionholder.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/Optionholder.java @@ -44,9 +44,9 @@ public class Optionholder extends ViewHolder implements OnClickListener { this.settings = settings; this.listener = listener; - optionName.setTextColor(settings.getFontColor()); + optionName.setTextColor(settings.getTextColor()); optionName.setTypeface(settings.getTypeFace()); - optionVotes.setTextColor(settings.getFontColor()); + optionVotes.setTextColor(settings.getTextColor()); optionVotes.setTypeface(settings.getTypeFace()); AppStyles.setSeekBarColor(voteProgress, settings); checkIcon.setColorFilter(settings.getIconColor()); diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/PlaceHolder.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/PlaceHolder.java index 67400b34..381ef00d 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/PlaceHolder.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/PlaceHolder.java @@ -43,9 +43,9 @@ public class PlaceHolder extends ViewHolder implements OnClickListener { loadBtn = itemView.findViewById(R.id.placeholder_button); background.setCardBackgroundColor(settings.getCardColor()); - loadBtn.setTextColor(settings.getFontColor()); + loadBtn.setTextColor(settings.getTextColor()); loadBtn.setTypeface(settings.getTypeFace()); - AppStyles.setButtonColor(loadBtn, settings.getFontColor()); + AppStyles.setButtonColor(loadBtn, settings.getTextColor()); AppStyles.setProgressColor(loadCircle, settings.getHighlightColor()); // enable extra views diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/PollHolder.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/PollHolder.java index 68bc5ba8..d7407442 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/PollHolder.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/PollHolder.java @@ -44,7 +44,7 @@ public class PollHolder extends ViewHolder implements OnClickListener { this.listener = listener; cardBackground.setCardBackgroundColor(settings.getCardColor()); - votesCount.setTextColor(settings.getFontColor()); + votesCount.setTextColor(settings.getTextColor()); votesCount.setTypeface(settings.getTypeFace()); itemView.getLayoutParams().width = parent.getMeasuredHeight() * 2; // 2:1 ratio diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/views/TabSelector.java b/app/src/main/java/org/nuclearfog/twidda/ui/views/TabSelector.java new file mode 100644 index 00000000..6cb70f61 --- /dev/null +++ b/app/src/main/java/org/nuclearfog/twidda/ui/views/TabSelector.java @@ -0,0 +1,224 @@ +package org.nuclearfog.twidda.ui.views; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewTreeObserver.OnGlobalLayoutListener; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.ArrayRes; +import androidx.annotation.Nullable; +import androidx.viewpager2.widget.ViewPager2; +import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback; + +import org.nuclearfog.twidda.R; +import org.nuclearfog.twidda.backend.utils.AppStyles; +import org.nuclearfog.twidda.config.GlobalSettings; + +/** + * TabLayout implementation to provide a tab selector + * + * @author nuclearfog + */ +public class TabSelector extends LinearLayout implements OnClickListener, OnGlobalLayoutListener { + + @Nullable + private ViewPager2 viewPager; + private LinearLayout tabContainer; + private View indicator; + + @Nullable + private OnTabSelectedListener listener; + private GlobalSettings settings; + + private int indicator_height; + private int oldPosition; + private int tabCount; + + /** + * @inheritDoc + */ + public TabSelector(Context context) { + this(context, null); + } + + /** + * @inheritDoc + */ + public TabSelector(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + setOrientation(VERTICAL); + settings = GlobalSettings.getInstance(context); + tabContainer = new LinearLayout(context); + tabContainer.setOrientation(LinearLayout.HORIZONTAL); + indicator = new View(context); + + indicator.setVisibility(INVISIBLE); + indicator_height = (int) getResources().getDimension(R.dimen.tabs_indicator_height); + LayoutParams tabContainerParam = new LayoutParams(LayoutParams.MATCH_PARENT, 0); + tabContainerParam.weight = 1; + + tabContainer.setLayoutParams(tabContainerParam); + addView(tabContainer); + addView(indicator); + } + + + @Override + public void onClick(View v) { + for (int i = 0 ; i < tabContainer.getChildCount(); i++) { + if (tabContainer.getChildAt(i) == v && listener != null) { + if (viewPager != null && viewPager.getAdapter() != null && i < viewPager.getAdapter().getItemCount()) { + listener.onTabSelected(oldPosition, i); + viewPager.setCurrentItem(i); + oldPosition = i; + } + break; + } + } + } + + + @Override + public void onGlobalLayout() { + getViewTreeObserver().removeOnGlobalLayoutListener(this); + for (int i = 0 ; i < tabContainer.getChildCount(); i++) { + View tabItemView = tabContainer.getChildAt(i); + ImageView icon = tabItemView.findViewById(R.id.tab_icon); + TextView label = tabItemView.findViewById(R.id.tab_text); + tabItemView.getLayoutParams().width = getMeasuredWidth() / Math.max(tabCount, 1); + tabItemView.getLayoutParams().height = getMeasuredHeight(); + AppStyles.setDrawableColor(icon, settings.getIconColor()); + label.setTextColor(settings.getTextColor()); + } + LayoutParams params = new LayoutParams(getMeasuredWidth() / Math.max(tabCount, 1), 5); + indicator.setLayoutParams(params); + indicator.setBackgroundColor(settings.getHighlightColor()); + indicator.setVisibility(VISIBLE); + } + + /** + * attach {@link ViewPager2} to this view + * + * @param viewPager ViewPager to interact with + */ + public void addViewPager(ViewPager2 viewPager) { + this.viewPager = viewPager; + viewPager.registerOnPageChangeCallback(new ViewPagerCallback()); + } + + /** + * set tab icons + * + * @param arrayRes array ID containing drawable IDs + */ + public void addTabIcons(@ArrayRes int arrayRes) { + TypedArray tArray = getResources().obtainTypedArray(arrayRes); + tabContainer.removeAllViews(); + if (viewPager != null && viewPager.getAdapter() != null) { + tabCount = Math.min(tArray.length(), viewPager.getAdapter().getItemCount()); + } else { + tabCount = tArray.length(); + } + for (int i = 0 ; i < tabCount ; i++) { + View tabItemView = inflate(getContext(), R.layout.item_tab, null); + ImageView icon = tabItemView.findViewById(R.id.tab_icon); + int resId = tArray.getResourceId(i, 0); + icon.setImageResource(resId); + tabContainer.addView(tabItemView); + tabItemView.setOnClickListener(this); + } + tArray.recycle(); + getViewTreeObserver().addOnGlobalLayoutListener(this); + } + + /** + * set tab item label + * + * @param position index of the tab item + * @param text text to set + */ + public void setLabel(int position, String text) { + if (position >= 0 && position < tabContainer.getChildCount()) { + View tabItemView = tabContainer.getChildAt(position); + TextView tabLabel = tabItemView.findViewById(R.id.tab_text); + tabLabel.setText(text); + tabLabel.setVisibility(VISIBLE); + } + } + + /** + * add listener to call when a tab is selected + */ + public void addOnTabSelectedListener(OnTabSelectedListener listener) { + this.listener = listener; + } + + /** + */ + private void setPosition(float positionOffset) { + if (viewPager != null && viewPager.getAdapter() != null && tabCount > 0) { + LayoutParams params = new LayoutParams(getMeasuredWidth() / tabCount, indicator_height); + params.setMarginStart((int) (getMeasuredWidth() * positionOffset / tabCount)); + indicator.setLayoutParams(params); + indicator.setVisibility(VISIBLE); + } + } + + /** + */ + private void setPage(int page) { + if (viewPager != null && viewPager.getAdapter() != null && page < viewPager.getAdapter().getItemCount() && page < tabCount) { + if (listener != null) { + listener.onTabSelected(oldPosition, page); + } + oldPosition = page; + } + } + + /** + * Listener to call when a new tab is selected + */ + public interface OnTabSelectedListener { + + /** + * called on tab item click + * + * @param oldPosition unselected position + * @param position selected position + */ + void onTabSelected(int oldPosition, int position); + } + + /** + * {@link ViewPager2} callback used to determine page & scroll position + */ + private class ViewPagerCallback extends OnPageChangeCallback { + + + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + super.onPageScrolled(position, positionOffset, positionOffsetPixels); + if (positionOffsetPixels > 0) { + setPosition(positionOffset + position); + } + } + + + @Override + public void onPageSelected(int position) { + super.onPageSelected(position); + setPage(position); + } + + + @Override + public void onPageScrollStateChanged(int state) { + super.onPageScrollStateChanged(state); + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/item_tab.xml b/app/src/main/res/layout/item_tab.xml index dd83127e..ab0a45a4 100644 --- a/app/src/main/res/layout/item_tab.xml +++ b/app/src/main/res/layout/item_tab.xml @@ -1,32 +1,26 @@ - + android:gravity="center_horizontal" + android:orientation="vertical" + android:padding="@dimen/item_tab_padding"> + android:textSize="@dimen/item_tab_textsize" + android:visibility="gone" /> - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/page_exclude.xml b/app/src/main/res/layout/page_exclude.xml index df122c69..880982c9 100644 --- a/app/src/main/res/layout/page_exclude.xml +++ b/app/src/main/res/layout/page_exclude.xml @@ -13,13 +13,12 @@ android:layout_width="match_parent" android:layout_height="wrap_content" /> - + android:layout_height="@dimen/tabselector_height" /> - - + android:layout_height="@dimen/tabselector_height" /> - diff --git a/app/src/main/res/layout/page_listdetail.xml b/app/src/main/res/layout/page_listdetail.xml index d0f4b9dd..4e46bdad 100644 --- a/app/src/main/res/layout/page_listdetail.xml +++ b/app/src/main/res/layout/page_listdetail.xml @@ -13,13 +13,12 @@ android:layout_width="match_parent" android:layout_height="wrap_content" /> - + android:layout_height="@dimen/tabselector_height" /> - diff --git a/app/src/main/res/layout/page_main.xml b/app/src/main/res/layout/page_main.xml index 44af27b9..b97545bf 100644 --- a/app/src/main/res/layout/page_main.xml +++ b/app/src/main/res/layout/page_main.xml @@ -13,15 +13,15 @@ android:layout_width="match_parent" android:layout_height="@dimen/mainpage_toolbar_height" /> - + android:layout_height="@dimen/tabselector_height" /> - + android:layout_height="match_parent" + android:orientation="horizontal"/> \ No newline at end of file diff --git a/app/src/main/res/layout/page_profile.xml b/app/src/main/res/layout/page_profile.xml index 41041e1a..48a773cb 100644 --- a/app/src/main/res/layout/page_profile.xml +++ b/app/src/main/res/layout/page_profile.xml @@ -223,14 +223,12 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + android:layout_height="@dimen/profile_tabselector_height" /> - diff --git a/app/src/main/res/layout/page_search.xml b/app/src/main/res/layout/page_search.xml index e0046fe7..e04d539c 100644 --- a/app/src/main/res/layout/page_search.xml +++ b/app/src/main/res/layout/page_search.xml @@ -13,13 +13,12 @@ android:layout_width="match_parent" android:layout_height="@dimen/searchpage_toolbar_height" /> - + android:layout_height="@dimen/tabselector_height" /> - diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 6af0d295..95c0a4df 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -3,6 +3,8 @@ 56dp 48dp + 40dp + 2dp 5dp 16sp 2dp @@ -54,8 +56,8 @@ 5dp 14sp 12sp - 120sp 14sp + 52dp 6 @@ -251,9 +253,10 @@ 20sp 22sp - - 22sp - 11sp + + 22sp + 11sp + 5dp 11sp