Skip to content

Commit ec8d4c6

Browse files
committed
Migrate ChatFragment to ViewPager2 (part 1)
1 parent ed71f5e commit ec8d4c6

File tree

2 files changed

+63
-84
lines changed

2 files changed

+63
-84
lines changed

app/src/main/java/com/perflyst/twire/fragments/ChatFragment.java

Lines changed: 61 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,16 @@
3535
import androidx.annotation.Nullable;
3636
import androidx.core.content.ContextCompat;
3737
import androidx.fragment.app.Fragment;
38-
import androidx.fragment.app.FragmentManager;
39-
import androidx.fragment.app.FragmentPagerAdapter;
4038
import androidx.recyclerview.widget.LinearLayoutManager;
4139
import androidx.recyclerview.widget.RecyclerView;
42-
import androidx.viewpager.widget.ViewPager;
40+
import androidx.viewpager2.adapter.FragmentStateAdapter;
41+
import androidx.viewpager2.widget.ViewPager2;
4342

4443
import com.bumptech.glide.Glide;
4544
import com.google.android.material.bottomsheet.BottomSheetBehavior;
4645
import com.google.android.material.bottomsheet.BottomSheetDialog;
4746
import com.google.android.material.tabs.TabLayout;
47+
import com.google.android.material.tabs.TabLayoutMediator;
4848
import com.perflyst.twire.R;
4949
import com.perflyst.twire.activities.stream.LiveStreamActivity;
5050
import com.perflyst.twire.adapters.ChatAdapter;
@@ -78,7 +78,12 @@ interface EmoteKeyboardDelegate {
7878
}
7979

8080
public class ChatFragment extends Fragment implements EmoteKeyboardDelegate, ChatAdapter.ChatAdapterCallback {
81-
private static final Integer[] supportedUnicodeEmotes = {
81+
private static final int POSITION_RECENT = 0;
82+
private static final int POSITION_TWITCH = 1;
83+
private static final int POSITION_SUBSCRIBER = 2;
84+
private static final int POSITION_CUSTOM = 3;
85+
private static final int POSITION_UNICODE = 4;
86+
private static final Integer[] supportedUnicodeEmotes = new Integer[]{
8287
0x1F600, 0x1F601, 0x1F602, 0x1F603, 0x1F604, 0x1F605, 0x1F606, 0x1F607, 0x1F608, 0x1F609, 0x1F60A, 0x1F60B, 0x1F60C, 0x1F60D, 0x1F60E, 0x1F60F,
8388
0x1F610, 0x1F611, 0x1F612, 0x1F613, 0x1F614, 0x1F615, 0x1F616, 0x1F617, 0x1F618, 0x1F619, 0x1F61A, 0x1F61B, 0x1F61C, 0x1F61D, 0x1F61E, 0x1F61F,
8489
0x1F620, 0x1F621, 0x1F622, 0x1F623, 0x1F624, 0x1F625, 0x1F626, 0x1F627, 0x1F628, 0x1F629, 0x1F62A, 0x1F62B, 0x1F62C, 0x1F62D, 0x1F62E, 0x1F62F,
@@ -117,7 +122,7 @@ public class ChatFragment extends Fragment implements EmoteKeyboardDelegate, Cha
117122
private ViewGroup emoteKeyboardContainer;
118123
private boolean isEmoteKeyboardOpen = false;
119124
private TabLayout mEmoteTabs;
120-
private ViewPager mEmoteViewPager;
125+
private ViewPager2 mEmoteViewPager;
121126
private Integer selectedTabColorRes, unselectedTabColorRes;
122127
private boolean hasSoftKeyboardBeenShown = false,
123128
hideKeyboardWhenShown = false,
@@ -462,7 +467,7 @@ private void subscriberEmotesLoaded(List<Emote> subscriberEmotesLoaded, EmotesPa
462467

463468
TabLayout.Tab newTab = mEmoteTabs.newTab();
464469
newTab.setIcon(icon);
465-
mEmoteTabs.addTab(newTab, adapter.SUBSCRIBER_POSITION, false);
470+
mEmoteTabs.addTab(newTab, POSITION_SUBSCRIBER, false);
466471
adapter.showSubscriberEmote = true;
467472
adapter.notifyDataSetChanged();
468473

@@ -590,28 +595,10 @@ private void setupEmoteTabs() {
590595
if (getActivity() == null)
591596
return;
592597

593-
final EmotesPagerAdapter pagerAdapter = new EmotesPagerAdapter(getActivity().getSupportFragmentManager());
594-
595-
for (int i = 0; i < mEmoteTabs.getTabCount(); i++) {
596-
TabLayout.Tab tab = mEmoteTabs.getTabAt(i);
597-
Drawable icon = tab != null ? tab.getIcon() : null;
598-
599-
if (icon != null) {
600-
if (i == 0) {
601-
icon.setColorFilter(new PorterDuffColorFilter(selectedTabColorRes, PorterDuff.Mode.SRC_IN));
602-
} else {
603-
icon.setColorFilter(new PorterDuffColorFilter(unselectedTabColorRes, PorterDuff.Mode.SRC_IN));
604-
}
605-
}
606-
}
598+
final EmotesPagerAdapter pagerAdapter = new EmotesPagerAdapter(this);
607599

608600
mEmoteViewPager.setAdapter(pagerAdapter);
609-
mEmoteViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
610-
@Override
611-
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
612-
613-
}
614-
601+
mEmoteViewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
615602
@Override
616603
public void onPageSelected(int position) {
617604
if (mEmoteTabs.getTabCount() - 1 >= position) {
@@ -620,37 +607,61 @@ public void onPageSelected(int position) {
620607
tab.select();
621608
}
622609
}
623-
624-
@Override
625-
public void onPageScrollStateChanged(int state) {
626-
627-
}
628610
});
629611

630612
mEmoteTabs.addOnTabSelectedListener(
631-
new TabLayout.ViewPagerOnTabSelectedListener(mEmoteViewPager) {
613+
new TabLayout.OnTabSelectedListener() {
632614
@Override
633615
public void onTabSelected(@NonNull TabLayout.Tab tab) {
634-
super.onTabSelected(tab);
635-
636616
if (tab.getIcon() != null)
637617
tab.getIcon().setColorFilter(new PorterDuffColorFilter(selectedTabColorRes, PorterDuff.Mode.SRC_IN));
638618
}
639619

640620
@Override
641621
public void onTabUnselected(TabLayout.Tab tab) {
642-
super.onTabUnselected(tab);
643622
if (tab.getIcon() != null)
644623
tab.getIcon().setColorFilter(new PorterDuffColorFilter(unselectedTabColorRes, PorterDuff.Mode.SRC_IN));
645624
}
646625

647626
@Override
648627
public void onTabReselected(TabLayout.Tab tab) {
649-
super.onTabReselected(tab);
650628
}
651629
}
652630
);
653631

632+
new TabLayoutMediator(mEmoteTabs, mEmoteViewPager, (tab, position) -> {
633+
for (int i = 0; i < mEmoteTabs.getTabCount(); i++) {
634+
TabLayout.Tab tab1 = mEmoteTabs.getTabAt(i);
635+
Drawable icon = tab1 != null ? tab1.getIcon() : null;
636+
637+
if (icon != null) {
638+
if (i == 0) {
639+
icon.setColorFilter(new PorterDuffColorFilter(selectedTabColorRes, PorterDuff.Mode.SRC_IN));
640+
} else {
641+
icon.setColorFilter(new PorterDuffColorFilter(unselectedTabColorRes, PorterDuff.Mode.SRC_IN));
642+
}
643+
}
644+
}
645+
switch (position) {
646+
default: // Deliberate fall-through to recent tab
647+
case POSITION_RECENT:
648+
tab.setIcon(R.drawable.ic_schedule);
649+
break;
650+
case POSITION_TWITCH:
651+
tab.setIcon(R.drawable.ic_twitch);
652+
break;
653+
case POSITION_SUBSCRIBER:
654+
tab.setIcon(R.drawable.ic_attach_money);
655+
break;
656+
case POSITION_CUSTOM:
657+
tab.setIcon(R.drawable.ic_betterttv_500px);
658+
break;
659+
case POSITION_UNICODE:
660+
tab.setIcon(R.drawable.ic_mood);
661+
break;
662+
}
663+
}).attach();
664+
654665
GetTwitchEmotesTask getTwitchEmotesTask = new GetTwitchEmotesTask((twitchEmotes, subscriberEmotes) -> {
655666
twitchEmotesLoaded(twitchEmotes);
656667
subscriberEmotesLoaded(subscriberEmotes, pagerAdapter);
@@ -936,10 +947,6 @@ static EmoteGridFragment newInstance(EmoteFragmentType fragmentType, EmoteKeyboa
936947
return emoteGridFragment;
937948
}
938949

939-
static EmoteGridFragment newInstance() {
940-
return new EmoteGridFragment();
941-
}
942-
943950
@Override
944951
public void onCreate(@Nullable Bundle savedInstanceState) {
945952
super.onCreate(savedInstanceState);
@@ -1139,16 +1146,11 @@ class EmoteViewHolder extends RecyclerView.ViewHolder {
11391146
}
11401147
}
11411148

1142-
private class EmotesPagerAdapter extends FragmentPagerAdapter {
1143-
final int RECENT_POSITION = 0,
1144-
TWITCH_POSITION = 1,
1145-
SUBSCRIBER_POSITION = 2,
1146-
CUSTOM_POSITION = 3,
1147-
UNICODE_POSITION = 4;
1149+
private class EmotesPagerAdapter extends FragmentStateAdapter {
11481150
boolean showSubscriberEmote = false;
11491151

1150-
EmotesPagerAdapter(FragmentManager fm) {
1151-
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
1152+
EmotesPagerAdapter(final Fragment f) {
1153+
super(f);
11521154
EmoteKeyboardDelegate delegate = ChatFragment.this;
11531155

11541156
recentEmotesFragment = EmoteGridFragment.newInstance(EmoteFragmentType.RECENT, delegate);
@@ -1158,32 +1160,31 @@ private class EmotesPagerAdapter extends FragmentPagerAdapter {
11581160
unicodeEmotesFragment = EmoteGridFragment.newInstance(EmoteFragmentType.UNICODE, delegate);
11591161
}
11601162

1161-
@Override
11621163
@NonNull
1163-
public Fragment getItem(int position) {
1164-
if (!showSubscriberEmote && position >= SUBSCRIBER_POSITION) {
1164+
@Override
1165+
public Fragment createFragment(int position) {
1166+
if (!showSubscriberEmote && position >= POSITION_SUBSCRIBER) {
11651167
position++;
11661168
}
11671169

11681170
switch (position) {
1169-
case RECENT_POSITION:
1171+
default: // Deliberate fall-through to recent tab
1172+
case POSITION_RECENT:
11701173
return recentEmotesFragment;
1171-
case TWITCH_POSITION:
1174+
case POSITION_TWITCH:
11721175
return twitchEmotesFragment;
1173-
case SUBSCRIBER_POSITION:
1176+
case POSITION_SUBSCRIBER:
11741177
return subscriberEmotesFragment;
1175-
case CUSTOM_POSITION:
1178+
case POSITION_CUSTOM:
11761179
return customEmotesFragment;
1177-
case UNICODE_POSITION:
1180+
case POSITION_UNICODE:
11781181
return unicodeEmotesFragment;
1179-
default:
1180-
return EmoteGridFragment.newInstance();
11811182
}
11821183
}
11831184

11841185
@Override
1185-
public int getCount() {
1186-
int count = UNICODE_POSITION + 1;
1186+
public int getItemCount() {
1187+
int count = POSITION_UNICODE + 1;
11871188
if (!showSubscriberEmote) {
11881189
count--;
11891190
}

app/src/main/res/layout/fragment_chat.xml

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -30,29 +30,7 @@
3030
android:layout_toLeftOf="@+id/backspace_divider"
3131
app:tabGravity="center"
3232
app:tabMaxWidth="@dimen/chat_emote_tab_max_width"
33-
app:tabMode="scrollable">
34-
35-
<com.google.android.material.tabs.TabItem
36-
android:layout_width="@dimen/chat_emote_tab_icon_size"
37-
android:layout_height="@dimen/chat_emote_tab_icon_size"
38-
android:icon="@drawable/ic_schedule" />
39-
40-
<com.google.android.material.tabs.TabItem
41-
android:layout_width="@dimen/chat_emote_tab_icon_size"
42-
android:layout_height="@dimen/chat_emote_tab_icon_size"
43-
android:icon="@drawable/ic_twitch" />
44-
45-
<com.google.android.material.tabs.TabItem
46-
android:layout_width="@dimen/chat_emote_tab_icon_size"
47-
android:layout_height="@dimen/chat_emote_tab_icon_size"
48-
android:icon="@drawable/ic_betterttv_500px" />
49-
50-
<com.google.android.material.tabs.TabItem
51-
android:layout_width="@dimen/chat_emote_tab_icon_size"
52-
android:layout_height="@dimen/chat_emote_tab_icon_size"
53-
android:icon="@drawable/ic_mood" />
54-
55-
</com.google.android.material.tabs.TabLayout>
33+
app:tabMode="scrollable" />
5634

5735
<View
5836
android:id="@+id/backspace_divider"
@@ -78,7 +56,7 @@
7856
android:layout_height="@dimen/chat_emote_divider"
7957
android:background="?attr/chatStatusBarColor" />
8058

81-
<androidx.viewpager.widget.ViewPager
59+
<androidx.viewpager2.widget.ViewPager2
8260
android:id="@+id/tabs_viewpager"
8361
android:layout_width="match_parent"
8462
android:layout_height="match_parent"

0 commit comments

Comments
 (0)