feat: use pager-based root tab navigation
This commit is contained in:
@@ -58,6 +58,7 @@ dependencies {
|
||||
implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion"
|
||||
implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion"
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
|
||||
implementation "androidx.viewpager2:viewpager2:1.1.0"
|
||||
testImplementation "junit:junit:$junitVersion"
|
||||
testImplementation "org.robolectric:robolectric:4.14.1"
|
||||
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
|
||||
|
||||
@@ -6,9 +6,10 @@ import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
@@ -19,7 +20,9 @@ import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
import androidx.viewpager2.widget.ViewPager2;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
@@ -60,6 +63,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
private Button tabConversations;
|
||||
private Button tabDevices;
|
||||
private Button tabMe;
|
||||
private ViewPager2 rootPager;
|
||||
private SwipeRefreshLayout screenRefresh;
|
||||
private ScrollView screenScroll;
|
||||
private LinearLayout screenContent;
|
||||
@@ -81,7 +85,8 @@ public class MainActivity extends AppCompatActivity {
|
||||
private boolean conversationAutoRefreshArmed = false;
|
||||
private boolean conversationAutoRefreshEnabled = false;
|
||||
private final Set<String> selectedConversationProjectIds = new LinkedHashSet<>();
|
||||
private @Nullable GestureDetector conversationPagerGestureDetector;
|
||||
private @Nullable RootPagerAdapter rootPagerAdapter;
|
||||
private boolean syncingRootPagerSelection = false;
|
||||
private final Runnable conversationAutoRefreshRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -175,9 +180,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
tabConversations = findViewById(R.id.tab_conversations);
|
||||
tabDevices = findViewById(R.id.tab_devices);
|
||||
tabMe = findViewById(R.id.tab_me);
|
||||
screenRefresh = findViewById(R.id.screen_refresh);
|
||||
screenScroll = findViewById(R.id.screen_scroll);
|
||||
screenContent = findViewById(R.id.screen_content);
|
||||
rootPager = findViewById(R.id.root_pager);
|
||||
|
||||
String[] rootTabs = WechatSurfaceMapper.rootTabLabels();
|
||||
tabConversations.setText(rootTabs[0]);
|
||||
@@ -197,47 +200,23 @@ public class MainActivity extends AppCompatActivity {
|
||||
tabConversations.setOnClickListener(v -> setActiveTab("conversations", true));
|
||||
tabDevices.setOnClickListener(v -> setActiveTab("devices", true));
|
||||
tabMe.setOnClickListener(v -> setActiveTab("me", true));
|
||||
screenRefresh.setOnRefreshListener(this::refreshCurrentTab);
|
||||
conversationPagerGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
|
||||
private static final int SWIPE_DISTANCE_THRESHOLD = 120;
|
||||
private static final int SWIPE_VELOCITY_THRESHOLD = 120;
|
||||
|
||||
rootPagerAdapter = new RootPagerAdapter();
|
||||
rootPager.setAdapter(rootPagerAdapter);
|
||||
rootPager.setOffscreenPageLimit(3);
|
||||
rootPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
|
||||
@Override
|
||||
public boolean onDown(MotionEvent e) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
||||
if (e1 == null || e2 == null) {
|
||||
return false;
|
||||
public void onPageSelected(int position) {
|
||||
if (syncingRootPagerSelection) {
|
||||
return;
|
||||
}
|
||||
float deltaX = e2.getX() - e1.getX();
|
||||
float deltaY = e2.getY() - e1.getY();
|
||||
if (Math.abs(deltaX) < Math.abs(deltaY)) {
|
||||
return false;
|
||||
}
|
||||
if (Math.abs(deltaX) < SWIPE_DISTANCE_THRESHOLD || Math.abs(velocityX) < SWIPE_VELOCITY_THRESHOLD) {
|
||||
return false;
|
||||
}
|
||||
handleHorizontalPageSwipe(deltaX < 0 ? 1 : -1);
|
||||
return true;
|
||||
handleRootPagerSelection(position);
|
||||
}
|
||||
});
|
||||
screenRefresh.setOnTouchListener((v, event) -> {
|
||||
if (conversationPagerGestureDetector != null) {
|
||||
conversationPagerGestureDetector.onTouchEvent(event);
|
||||
}
|
||||
return false;
|
||||
rootPager.post(() -> {
|
||||
syncActivePageViews(activeTab);
|
||||
renderCurrentTab();
|
||||
updateConversationAutoRefresh();
|
||||
});
|
||||
if (screenScroll != null) {
|
||||
screenScroll.setOnTouchListener((v, event) -> {
|
||||
if (conversationPagerGestureDetector != null) {
|
||||
conversationPagerGestureDetector.onTouchEvent(event);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void applyInitialTab(@Nullable Intent intent) {
|
||||
@@ -462,6 +441,8 @@ public class MainActivity extends AppCompatActivity {
|
||||
}
|
||||
lastRootBackPressedAt = 0L;
|
||||
updateTabStyles();
|
||||
syncRootPager(tab, fromUser);
|
||||
syncActivePageViews(tab);
|
||||
renderCurrentTab();
|
||||
updateConversationAutoRefresh();
|
||||
}
|
||||
@@ -552,6 +533,9 @@ public class MainActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void renderConversationsRoot() {
|
||||
if (screenContent == null) {
|
||||
return;
|
||||
}
|
||||
screenContent.removeAllViews();
|
||||
screenContent.addView(buildConversationSearchInput());
|
||||
if (conversationSelectionMode) {
|
||||
@@ -756,20 +740,14 @@ public class MainActivity extends AppCompatActivity {
|
||||
});
|
||||
}
|
||||
|
||||
private void handleHorizontalPageSwipe(int direction) {
|
||||
String[] order = new String[] {"conversations", "devices", "me"};
|
||||
int currentIndex = 0;
|
||||
for (int i = 0; i < order.length; i++) {
|
||||
if (order[i].equals(activeTab)) {
|
||||
currentIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int nextIndex = currentIndex + direction;
|
||||
if (nextIndex < 0 || nextIndex >= order.length) {
|
||||
private void handleRootPagerSelection(int position) {
|
||||
String tab = tabForIndex(position);
|
||||
if (tab.equals(activeTab)) {
|
||||
syncActivePageViews(tab);
|
||||
updateConversationAutoRefresh();
|
||||
return;
|
||||
}
|
||||
setActiveTab(order[nextIndex], true);
|
||||
setActiveTab(tab, true);
|
||||
}
|
||||
|
||||
private EditText buildConversationSearchInput() {
|
||||
@@ -848,6 +826,9 @@ public class MainActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void renderDevicesRoot() {
|
||||
if (screenContent == null) {
|
||||
return;
|
||||
}
|
||||
screenContent.removeAllViews();
|
||||
if (devicesData == null || devicesData.length() == 0) {
|
||||
screenContent.addView(BossUi.buildEmptyCard(this, "当前没有接入设备。"));
|
||||
@@ -875,6 +856,9 @@ public class MainActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void renderMeRoot() {
|
||||
if (screenContent == null) {
|
||||
return;
|
||||
}
|
||||
screenContent.removeAllViews();
|
||||
String displayName = sessionData == null
|
||||
? apiClient.getDisplayName()
|
||||
@@ -945,6 +929,9 @@ public class MainActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void startRefreshing(boolean refreshing) {
|
||||
if (screenRefresh == null) {
|
||||
return;
|
||||
}
|
||||
screenRefresh.setRefreshing(refreshing);
|
||||
syncTopActionVisualState(refreshing);
|
||||
if (!refreshing) {
|
||||
@@ -1113,4 +1100,144 @@ public class MainActivity extends AppCompatActivity {
|
||||
return getSharedPreferences(UI_PREFS, MODE_PRIVATE)
|
||||
.getString(KEY_LAST_ROOT_TAB, null);
|
||||
}
|
||||
|
||||
private void syncRootPager(String tab, boolean smoothScroll) {
|
||||
if (rootPager == null) {
|
||||
return;
|
||||
}
|
||||
int targetIndex = indexForTab(tab);
|
||||
if (targetIndex < 0 || rootPager.getCurrentItem() == targetIndex) {
|
||||
return;
|
||||
}
|
||||
syncingRootPagerSelection = true;
|
||||
rootPager.setCurrentItem(targetIndex, smoothScroll);
|
||||
rootPager.post(() -> syncingRootPagerSelection = false);
|
||||
}
|
||||
|
||||
private void syncActivePageViews(String tab) {
|
||||
if (rootPagerAdapter == null) {
|
||||
screenRefresh = null;
|
||||
screenScroll = null;
|
||||
screenContent = null;
|
||||
return;
|
||||
}
|
||||
RootPageViewHolder holder = rootPagerAdapter.findHolder(tab);
|
||||
if (holder == null) {
|
||||
screenRefresh = null;
|
||||
screenScroll = null;
|
||||
screenContent = null;
|
||||
rootPager.post(() -> {
|
||||
RootPageViewHolder pendingHolder = rootPagerAdapter.findHolder(activeTab);
|
||||
if (pendingHolder != null) {
|
||||
screenRefresh = pendingHolder.refresh;
|
||||
screenScroll = pendingHolder.scroll;
|
||||
screenContent = pendingHolder.content;
|
||||
renderCurrentTab();
|
||||
updateConversationAutoRefresh();
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
screenRefresh = holder.refresh;
|
||||
screenScroll = holder.scroll;
|
||||
screenContent = holder.content;
|
||||
}
|
||||
|
||||
private static int indexForTab(String tab) {
|
||||
switch (tab) {
|
||||
case "devices":
|
||||
return 1;
|
||||
case "me":
|
||||
return 2;
|
||||
case "conversations":
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static String tabForIndex(int index) {
|
||||
switch (index) {
|
||||
case 1:
|
||||
return "devices";
|
||||
case 2:
|
||||
return "me";
|
||||
case 0:
|
||||
default:
|
||||
return "conversations";
|
||||
}
|
||||
}
|
||||
|
||||
private final class RootPagerAdapter extends RecyclerView.Adapter<RootPageViewHolder> {
|
||||
private final String[] tabs = new String[] {"conversations", "devices", "me"};
|
||||
private final RootPageViewHolder[] holders = new RootPageViewHolder[tabs.length];
|
||||
|
||||
RootPagerAdapter() {
|
||||
LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
|
||||
for (int i = 0; i < tabs.length; i++) {
|
||||
RootPageViewHolder holder = RootPageViewHolder.create(inflater, rootPager, tabs[i]);
|
||||
holder.refresh.setOnRefreshListener(() -> {
|
||||
if (!holder.tab.equals(activeTab)) {
|
||||
setActiveTab(holder.tab, true);
|
||||
return;
|
||||
}
|
||||
refreshCurrentTab();
|
||||
});
|
||||
holders[i] = holder;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return tabs.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RootPageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
RootPageViewHolder holder = holders[viewType];
|
||||
ViewParent currentParent = holder.itemView.getParent();
|
||||
if (currentParent instanceof ViewGroup) {
|
||||
((ViewGroup) currentParent).removeView(holder.itemView);
|
||||
}
|
||||
return holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(RootPageViewHolder holder, int position) {
|
||||
holders[position] = holder;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
RootPageViewHolder findHolder(String tab) {
|
||||
int index = indexForTab(tab);
|
||||
if (index < 0 || index >= holders.length) {
|
||||
return null;
|
||||
}
|
||||
return holders[index];
|
||||
}
|
||||
}
|
||||
|
||||
private static final class RootPageViewHolder extends RecyclerView.ViewHolder {
|
||||
final String tab;
|
||||
final SwipeRefreshLayout refresh;
|
||||
final ScrollView scroll;
|
||||
final LinearLayout content;
|
||||
|
||||
static RootPageViewHolder create(LayoutInflater inflater, ViewGroup parent, String tab) {
|
||||
View view = inflater.inflate(R.layout.view_root_tab_page, parent, false);
|
||||
return new RootPageViewHolder(view, tab);
|
||||
}
|
||||
|
||||
RootPageViewHolder(View itemView, String tab) {
|
||||
super(itemView);
|
||||
this.tab = tab;
|
||||
this.refresh = itemView.findViewById(R.id.root_page_refresh);
|
||||
this.scroll = itemView.findViewById(R.id.root_page_scroll);
|
||||
this.content = itemView.findViewById(R.id.root_page_content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="20dp"
|
||||
android:paddingTop="14dp"
|
||||
android:paddingRight="32dp"
|
||||
android:paddingRight="20dp"
|
||||
android:paddingBottom="12dp">
|
||||
|
||||
<Button
|
||||
@@ -142,7 +142,6 @@
|
||||
android:id="@+id/refresh_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="8dp"
|
||||
android:background="@drawable/bg_secondary_button"
|
||||
android:minWidth="0dp"
|
||||
android:paddingLeft="12dp"
|
||||
@@ -160,29 +159,10 @@
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/screen_refresh"
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/root_pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/screen_scroll"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/screen_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/boss_bg_app"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:paddingBottom="88dp" />
|
||||
</ScrollView>
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
android:layout_height="match_parent" />
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
||||
24
android/app/src/main/res/layout/view_root_tab_page.xml
Normal file
24
android/app/src/main/res/layout/view_root_tab_page.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/root_page_refresh"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/root_page_scroll"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/root_page_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/boss_bg_app"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:paddingBottom="88dp" />
|
||||
</ScrollView>
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
@@ -13,6 +13,7 @@ import org.junit.runner.RunWith;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@@ -53,9 +54,11 @@ public class MainActivityConversationSearchTest {
|
||||
.put("latestReplyLabel", "09:40")));
|
||||
|
||||
ReflectionHelpers.callInstanceMethod(activity, "showContent");
|
||||
Shadows.shadowOf(activity.getMainLooper()).idle();
|
||||
ReflectionHelpers.callInstanceMethod(activity, "renderConversationsRoot");
|
||||
Shadows.shadowOf(activity.getMainLooper()).idle();
|
||||
|
||||
LinearLayout content = activity.findViewById(R.id.screen_content);
|
||||
LinearLayout content = ReflectionHelpers.getField(activity, "screenContent");
|
||||
assertTrue(content.getChildAt(0) instanceof EditText);
|
||||
EditText input = (EditText) content.getChildAt(0);
|
||||
assertEquals("搜索项目或线程", String.valueOf(input.getHint()));
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.junit.runner.RunWith;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@@ -25,23 +26,24 @@ public class MainActivityConversationSelectionTest {
|
||||
MainActivity activity = Robolectric.buildActivity(MainActivity.class).setup().get();
|
||||
ReflectionHelpers.setField(activity, "conversationsData", buildConversations());
|
||||
ReflectionHelpers.callInstanceMethod(activity, "showContent");
|
||||
Shadows.shadowOf(activity.getMainLooper()).idle();
|
||||
|
||||
ReflectionHelpers.callInstanceMethod(activity, "enterConversationSelectionMode");
|
||||
assertTrue(ReflectionHelpers.getField(activity, "conversationSelectionMode"));
|
||||
|
||||
LinearLayout content = activity.findViewById(R.id.screen_content);
|
||||
LinearLayout content = ReflectionHelpers.getField(activity, "screenContent");
|
||||
assertTrue(viewTreeContainsText(content, "发起群聊"));
|
||||
assertTrue(viewTreeContainsText(content, "至少选择 2 个线程"));
|
||||
|
||||
ReflectionHelpers.callInstanceMethod(activity, "toggleConversationSelection",
|
||||
ReflectionHelpers.ClassParameter.from(String.class, "thread-1"));
|
||||
content = activity.findViewById(R.id.screen_content);
|
||||
content = ReflectionHelpers.getField(activity, "screenContent");
|
||||
assertTrue(viewTreeContainsText(content, "已选 1 个线程"));
|
||||
assertTrue(viewTreeContainsText(content, "至少选择 2 个线程"));
|
||||
|
||||
ReflectionHelpers.callInstanceMethod(activity, "toggleConversationSelection",
|
||||
ReflectionHelpers.ClassParameter.from(String.class, "thread-2"));
|
||||
content = activity.findViewById(R.id.screen_content);
|
||||
content = ReflectionHelpers.getField(activity, "screenContent");
|
||||
assertTrue(viewTreeContainsText(content, "已选 2 个线程"));
|
||||
assertFalse(viewTreeContainsText(content, "至少选择 2 个线程"));
|
||||
}
|
||||
@@ -51,9 +53,10 @@ public class MainActivityConversationSelectionTest {
|
||||
MainActivity activity = Robolectric.buildActivity(MainActivity.class).setup().get();
|
||||
ReflectionHelpers.setField(activity, "conversationsData", buildConversations());
|
||||
ReflectionHelpers.callInstanceMethod(activity, "showContent");
|
||||
Shadows.shadowOf(activity.getMainLooper()).idle();
|
||||
ReflectionHelpers.callInstanceMethod(activity, "enterConversationSelectionMode");
|
||||
|
||||
LinearLayout content = activity.findViewById(R.id.screen_content);
|
||||
LinearLayout content = ReflectionHelpers.getField(activity, "screenContent");
|
||||
View row = content.getChildAt(3);
|
||||
assertTrue("多选模式应显示单选圆点", viewTreeContainsContentDescription(row, "未选中会话"));
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.junit.runner.RunWith;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@@ -40,9 +41,11 @@ public class MainActivityPinnedConversationsTest {
|
||||
.put("latestReplyLabel", "09:41")));
|
||||
|
||||
ReflectionHelpers.callInstanceMethod(activity, "showContent");
|
||||
Shadows.shadowOf(activity.getMainLooper()).idle();
|
||||
ReflectionHelpers.callInstanceMethod(activity, "renderConversationsRoot");
|
||||
Shadows.shadowOf(activity.getMainLooper()).idle();
|
||||
|
||||
LinearLayout content = activity.findViewById(R.id.screen_content);
|
||||
LinearLayout content = ReflectionHelpers.getField(activity, "screenContent");
|
||||
assertTrue(viewTreeContainsText(content, "置顶会话"));
|
||||
assertTrue(viewTreeContainsText(content, "收起"));
|
||||
assertTrue(viewTreeContainsText(content, "主 Agent"));
|
||||
|
||||
@@ -1,32 +1,51 @@
|
||||
package com.hyzq.boss;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import androidx.viewpager2.widget.ViewPager2;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(sdk = 34)
|
||||
public class MainActivitySwipeNavigationTest {
|
||||
@Test
|
||||
public void horizontalSwipeMovesBetweenRootTabs() {
|
||||
public void selectingTabsUpdatesPagerAndActiveTab() {
|
||||
MainActivity activity = Robolectric.buildActivity(MainActivity.class).setup().get();
|
||||
ReflectionHelpers.callInstanceMethod(activity, "showContent");
|
||||
ViewPager2 pager = activity.findViewById(R.id.root_pager);
|
||||
assertNotNull(pager);
|
||||
|
||||
ReflectionHelpers.callInstanceMethod(activity, "handleHorizontalPageSwipe",
|
||||
ReflectionHelpers.ClassParameter.from(int.class, 1));
|
||||
activity.findViewById(R.id.tab_devices).performClick();
|
||||
Shadows.shadowOf(activity.getMainLooper()).idle();
|
||||
assertEquals(1, pager.getCurrentItem());
|
||||
assertEquals("devices", ReflectionHelpers.getField(activity, "activeTab"));
|
||||
|
||||
ReflectionHelpers.callInstanceMethod(activity, "handleHorizontalPageSwipe",
|
||||
ReflectionHelpers.ClassParameter.from(int.class, 1));
|
||||
activity.findViewById(R.id.tab_me).performClick();
|
||||
Shadows.shadowOf(activity.getMainLooper()).idle();
|
||||
assertEquals(2, pager.getCurrentItem());
|
||||
assertEquals("me", ReflectionHelpers.getField(activity, "activeTab"));
|
||||
}
|
||||
|
||||
ReflectionHelpers.callInstanceMethod(activity, "handleHorizontalPageSwipe",
|
||||
ReflectionHelpers.ClassParameter.from(int.class, -1));
|
||||
@Test
|
||||
public void pagerSelectionUpdatesActiveTab() {
|
||||
MainActivity activity = Robolectric.buildActivity(MainActivity.class).setup().get();
|
||||
ReflectionHelpers.callInstanceMethod(activity, "showContent");
|
||||
ViewPager2 pager = activity.findViewById(R.id.root_pager);
|
||||
assertNotNull(pager);
|
||||
|
||||
pager.setCurrentItem(1, false);
|
||||
Shadows.shadowOf(activity.getMainLooper()).idle();
|
||||
assertEquals("devices", ReflectionHelpers.getField(activity, "activeTab"));
|
||||
|
||||
pager.setCurrentItem(2, false);
|
||||
Shadows.shadowOf(activity.getMainLooper()).idle();
|
||||
assertEquals("me", ReflectionHelpers.getField(activity, "activeTab"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user