Fix conversation media overview underline flicker.
This commit is contained in:
parent
f2a490b07e
commit
911dd9efb1
5 changed files with 118 additions and 35 deletions
|
@ -4,6 +4,9 @@ import android.content.Context;
|
|||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -15,6 +18,8 @@ public class ControllableTabLayout extends TabLayout {
|
|||
|
||||
private List<View> touchables;
|
||||
|
||||
private NewTabListener newTabListener;
|
||||
|
||||
public ControllableTabLayout(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
@ -39,4 +44,28 @@ public class ControllableTabLayout extends TabLayout {
|
|||
|
||||
super.setEnabled(enabled);
|
||||
}
|
||||
|
||||
public void setNewTabListener(@Nullable NewTabListener newTabListener) {
|
||||
this.newTabListener = newTabListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Tab newTab() {
|
||||
Tab tab = super.newTab();
|
||||
|
||||
if (newTabListener != null) {
|
||||
newTabListener.onNewTab(tab);
|
||||
}
|
||||
|
||||
return tab;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows implementor to modify tabs when they are created, before they are added to the tab layout.
|
||||
* This is useful for loading custom views, to ensure that time is not spent inflating these views
|
||||
* as the user is switching between pages.
|
||||
*/
|
||||
public interface NewTabListener {
|
||||
void onNewTab(@NonNull Tab tab);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ package org.thoughtcrime.securesms.mediaoverview;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
@ -27,19 +26,19 @@ import android.widget.TextView;
|
|||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentStatePagerAdapter;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.AnimatingToggle;
|
||||
import org.thoughtcrime.securesms.components.ControllableTabLayout;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.MediaDatabase;
|
||||
import org.thoughtcrime.securesms.database.MediaDatabase.Sorting;
|
||||
|
@ -51,6 +50,7 @@ import org.whispersystems.libsignal.util.Pair;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Activity for displaying media attachments in-app
|
||||
|
@ -62,7 +62,7 @@ public final class MediaOverviewActivity extends PassphraseRequiredActivity {
|
|||
private final DynamicTheme dynamicTheme = new DynamicNoActionBarTheme();
|
||||
|
||||
private Toolbar toolbar;
|
||||
private TabLayout tabLayout;
|
||||
private ControllableTabLayout tabLayout;
|
||||
private ViewPager viewPager;
|
||||
private TextView sortOrder;
|
||||
private View sortOrderArrow;
|
||||
|
@ -98,6 +98,7 @@ public final class MediaOverviewActivity extends PassphraseRequiredActivity {
|
|||
|
||||
boolean allThreads = threadId == MediaDatabase.ALL_THREADS;
|
||||
|
||||
tabLayout.setNewTabListener(new NewTabListener());
|
||||
tabLayout.addOnTabSelectedListener(new OnTabSelectedListener());
|
||||
fillTabLayoutIfFits(tabLayout);
|
||||
tabLayout.setupWithViewPager(viewPager);
|
||||
|
@ -221,7 +222,7 @@ public final class MediaOverviewActivity extends PassphraseRequiredActivity {
|
|||
}
|
||||
|
||||
private void showSortOrderDialog(View v) {
|
||||
new AlertDialog.Builder(MediaOverviewActivity.this)
|
||||
new MaterialAlertDialogBuilder(MediaOverviewActivity.this)
|
||||
.setTitle(R.string.MediaOverviewActivity_Sort_by)
|
||||
.setSingleChoiceItems(R.array.MediaOverviewActivity_Sort_by,
|
||||
currentSorting.ordinal(),
|
||||
|
@ -286,39 +287,33 @@ public final class MediaOverviewActivity extends PassphraseRequiredActivity {
|
|||
}
|
||||
}
|
||||
|
||||
private static final class OnTabSelectedListener implements TabLayout.OnTabSelectedListener {
|
||||
private static final class NewTabListener implements ControllableTabLayout.NewTabListener {
|
||||
@Override
|
||||
public void onNewTab(@NonNull TabLayout.Tab tab) {
|
||||
View customView = tab.getCustomView();
|
||||
if (customView == null) {
|
||||
tab.setCustomView(R.layout.media_overview_tab_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final Typeface tabUnselected = Typeface.create("sans-serif", Typeface.NORMAL);
|
||||
private final Typeface tabSelected = Typeface.create("sans-serif-medium", Typeface.NORMAL);
|
||||
private static final class OnTabSelectedListener implements TabLayout.OnTabSelectedListener {
|
||||
|
||||
@Override
|
||||
public void onTabSelected(@NonNull TabLayout.Tab tab) {
|
||||
View view = getCustomView(tab);
|
||||
TextView title = view.findViewById(android.R.id.text1);
|
||||
title.setTypeface(tabSelected);
|
||||
title.setTextColor(ContextCompat.getColor(view.getContext(), R.color.signal_inverse_primary));
|
||||
MediaOverviewTabItem view = (MediaOverviewTabItem) Objects.requireNonNull(tab.getCustomView());
|
||||
view.select();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabUnselected(@NonNull TabLayout.Tab tab) {
|
||||
View view = getCustomView(tab);
|
||||
TextView title = view.findViewById(android.R.id.text1);
|
||||
title.setTypeface(tabUnselected);
|
||||
title.setTextColor(ContextCompat.getColor(view.getContext(), R.color.signal_text_secondary));
|
||||
MediaOverviewTabItem view = (MediaOverviewTabItem) Objects.requireNonNull(tab.getCustomView());
|
||||
view.unselect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabReselected(@NonNull TabLayout.Tab tab) {
|
||||
// Intentionally Blank.
|
||||
}
|
||||
|
||||
private @NonNull View getCustomView(@NonNull TabLayout.Tab tab) {
|
||||
View customView = tab.getCustomView();
|
||||
if (customView == null) {
|
||||
tab.setCustomView(R.layout.custom_tab_layout_text);
|
||||
}
|
||||
|
||||
return tab.getCustomView();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package org.thoughtcrime.securesms.mediaoverview
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.widget.doAfterTextChanged
|
||||
import org.thoughtcrime.securesms.R
|
||||
|
||||
class MediaOverviewTabItem @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : FrameLayout(context, attrs, defStyleAttr) {
|
||||
|
||||
private lateinit var unselectedTextView: TextView
|
||||
private lateinit var selectedTextView: TextView
|
||||
|
||||
override fun onFinishInflate() {
|
||||
super.onFinishInflate()
|
||||
|
||||
unselectedTextView = findViewById(android.R.id.text1)
|
||||
selectedTextView = findViewById(R.id.text1_bold)
|
||||
|
||||
unselectedTextView.doAfterTextChanged {
|
||||
selectedTextView.text = it
|
||||
}
|
||||
}
|
||||
|
||||
fun select() {
|
||||
unselectedTextView.alpha = 0f
|
||||
selectedTextView.alpha = 1f
|
||||
}
|
||||
|
||||
fun unselect() {
|
||||
unselectedTextView.alpha = 1f
|
||||
selectedTextView.alpha = 0f
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@android:id/text1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textAppearance="@style/TextAppearance.Signal.Body2"
|
||||
android:maxLines="2"
|
||||
tools:text="Media" />
|
30
app/src/main/res/layout/media_overview_tab_item.xml
Normal file
30
app/src/main/res/layout/media_overview_tab_item.xml
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.thoughtcrime.securesms.mediaoverview.MediaOverviewTabItem xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/text1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha="1"
|
||||
android:gravity="center"
|
||||
android:maxLines="2"
|
||||
android:textAppearance="@style/TextAppearance.Signal.Body2"
|
||||
android:textColor="@color/signal_text_secondary"
|
||||
tools:text="Media" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text1_bold"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha="0"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:gravity="center"
|
||||
android:maxLines="2"
|
||||
android:textAppearance="@style/TextAppearance.Signal.Body2"
|
||||
android:textColor="@color/signal_text_primary"
|
||||
tools:text="Media" />
|
||||
|
||||
</org.thoughtcrime.securesms.mediaoverview.MediaOverviewTabItem>
|
Loading…
Add table
Reference in a new issue