perf: move root surfaces to recycler-backed pages
This commit is contained in:
@@ -3,8 +3,11 @@ package com.hyzq.boss;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
@@ -58,9 +61,19 @@ public class MainActivityConversationSearchTest {
|
||||
ReflectionHelpers.callInstanceMethod(activity, "renderConversationsRoot");
|
||||
Shadows.shadowOf(activity.getMainLooper()).idle();
|
||||
|
||||
LinearLayout content = ReflectionHelpers.getField(activity, "screenContent");
|
||||
assertTrue(content.getChildAt(0) instanceof EditText);
|
||||
EditText input = (EditText) content.getChildAt(0);
|
||||
RecyclerView list = ReflectionHelpers.getField(activity, "screenList");
|
||||
View firstItem = buildRecyclerItem(list, 0);
|
||||
assertTrue(firstItem instanceof EditText);
|
||||
EditText input = (EditText) firstItem;
|
||||
assertEquals("搜索项目或线程", String.valueOf(input.getHint()));
|
||||
}
|
||||
|
||||
private static View buildRecyclerItem(RecyclerView recyclerView, int position) {
|
||||
RecyclerView.Adapter adapter = recyclerView.getAdapter();
|
||||
int viewType = adapter.getItemViewType(position);
|
||||
RecyclerView.ViewHolder holder = adapter.createViewHolder(recyclerView, viewType);
|
||||
adapter.bindViewHolder(holder, position);
|
||||
FrameLayout container = (FrameLayout) holder.itemView;
|
||||
return container.getChildAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,12 @@ import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.Test;
|
||||
@@ -31,21 +34,19 @@ public class MainActivityConversationSelectionTest {
|
||||
ReflectionHelpers.callInstanceMethod(activity, "enterConversationSelectionMode");
|
||||
assertTrue(ReflectionHelpers.getField(activity, "conversationSelectionMode"));
|
||||
|
||||
LinearLayout content = ReflectionHelpers.getField(activity, "screenContent");
|
||||
assertTrue(viewTreeContainsText(content, "发起群聊"));
|
||||
assertTrue(viewTreeContainsText(content, "至少选择 2 个线程"));
|
||||
RecyclerView list = ReflectionHelpers.getField(activity, "screenList");
|
||||
assertTrue(recyclerContainsText(list, "发起群聊"));
|
||||
assertTrue(recyclerContainsText(list, "至少选择 2 个线程"));
|
||||
|
||||
ReflectionHelpers.callInstanceMethod(activity, "toggleConversationSelection",
|
||||
ReflectionHelpers.ClassParameter.from(String.class, "thread-1"));
|
||||
content = ReflectionHelpers.getField(activity, "screenContent");
|
||||
assertTrue(viewTreeContainsText(content, "已选 1 个线程"));
|
||||
assertTrue(viewTreeContainsText(content, "至少选择 2 个线程"));
|
||||
assertTrue(recyclerContainsText(list, "已选 1 个线程"));
|
||||
assertTrue(recyclerContainsText(list, "至少选择 2 个线程"));
|
||||
|
||||
ReflectionHelpers.callInstanceMethod(activity, "toggleConversationSelection",
|
||||
ReflectionHelpers.ClassParameter.from(String.class, "thread-2"));
|
||||
content = ReflectionHelpers.getField(activity, "screenContent");
|
||||
assertTrue(viewTreeContainsText(content, "已选 2 个线程"));
|
||||
assertFalse(viewTreeContainsText(content, "至少选择 2 个线程"));
|
||||
assertTrue(recyclerContainsText(list, "已选 2 个线程"));
|
||||
assertFalse(recyclerContainsText(list, "至少选择 2 个线程"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -56,11 +57,30 @@ public class MainActivityConversationSelectionTest {
|
||||
Shadows.shadowOf(activity.getMainLooper()).idle();
|
||||
ReflectionHelpers.callInstanceMethod(activity, "enterConversationSelectionMode");
|
||||
|
||||
LinearLayout content = ReflectionHelpers.getField(activity, "screenContent");
|
||||
View row = content.getChildAt(3);
|
||||
RecyclerView list = ReflectionHelpers.getField(activity, "screenList");
|
||||
View row = getRecyclerChild(list, 3);
|
||||
assertTrue("多选模式应显示单选圆点", viewTreeContainsContentDescription(row, "未选中会话"));
|
||||
}
|
||||
|
||||
private static View getRecyclerChild(RecyclerView recyclerView, int position) {
|
||||
RecyclerView.Adapter adapter = recyclerView.getAdapter();
|
||||
int viewType = adapter.getItemViewType(position);
|
||||
RecyclerView.ViewHolder holder = adapter.createViewHolder(recyclerView, viewType);
|
||||
adapter.bindViewHolder(holder, position);
|
||||
FrameLayout container = (FrameLayout) holder.itemView;
|
||||
return container.getChildAt(0);
|
||||
}
|
||||
|
||||
private static boolean recyclerContainsText(RecyclerView recyclerView, String expectedText) {
|
||||
RecyclerView.Adapter adapter = recyclerView.getAdapter();
|
||||
for (int index = 0; index < adapter.getItemCount(); index += 1) {
|
||||
if (viewTreeContainsText(getRecyclerChild(recyclerView, index), expectedText)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static JSONArray buildConversations() throws Exception {
|
||||
return new JSONArray()
|
||||
.put(new JSONObject()
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.hyzq.boss;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.View.MeasureSpec;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
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 MainActivityDevicesRootTest {
|
||||
@Test
|
||||
public void devicesTab_hidesLegacySubtitleAndUsesRecyclerList() throws Exception {
|
||||
MainActivity activity = Robolectric.buildActivity(MainActivity.class).setup().get();
|
||||
ReflectionHelpers.setField(activity, "devicesData", new JSONArray()
|
||||
.put(new JSONObject()
|
||||
.put("id", "mac-studio")
|
||||
.put("name", "Mac Studio")
|
||||
.put("status", "online")
|
||||
.put("platform", "macOS")
|
||||
.put("account", "17600003315")));
|
||||
|
||||
ReflectionHelpers.callInstanceMethod(activity, "showContent");
|
||||
ReflectionHelpers.callInstanceMethod(activity, "setActiveTab",
|
||||
ReflectionHelpers.ClassParameter.from(String.class, "devices"),
|
||||
ReflectionHelpers.ClassParameter.from(boolean.class, false));
|
||||
Shadows.shadowOf(activity.getMainLooper()).idle();
|
||||
|
||||
TextView subtitle = activity.findViewById(R.id.top_subtitle);
|
||||
assertEquals(View.GONE, subtitle.getVisibility());
|
||||
|
||||
RecyclerView list = ReflectionHelpers.getField(activity, "screenList");
|
||||
layoutRecyclerView(list);
|
||||
assertTrue(list.getVisibility() == View.VISIBLE);
|
||||
assertTrue(list.getAdapter().getItemCount() > 0);
|
||||
}
|
||||
|
||||
private static void layoutRecyclerView(RecyclerView recyclerView) {
|
||||
int widthSpec = MeasureSpec.makeMeasureSpec(1080, MeasureSpec.EXACTLY);
|
||||
int heightSpec = MeasureSpec.makeMeasureSpec(2400, MeasureSpec.EXACTLY);
|
||||
recyclerView.measure(widthSpec, heightSpec);
|
||||
recyclerView.layout(0, 0, 1080, 2400);
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,12 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.Test;
|
||||
@@ -45,18 +48,37 @@ public class MainActivityPinnedConversationsTest {
|
||||
ReflectionHelpers.callInstanceMethod(activity, "renderConversationsRoot");
|
||||
Shadows.shadowOf(activity.getMainLooper()).idle();
|
||||
|
||||
LinearLayout content = ReflectionHelpers.getField(activity, "screenContent");
|
||||
assertTrue(viewTreeContainsText(content, "置顶会话"));
|
||||
assertTrue(viewTreeContainsText(content, "收起"));
|
||||
assertTrue(viewTreeContainsText(content, "主 Agent"));
|
||||
assertTrue(viewTreeContainsText(content, "Boss 移动控制台"));
|
||||
RecyclerView list = ReflectionHelpers.getField(activity, "screenList");
|
||||
assertTrue(recyclerContainsText(list, "置顶会话"));
|
||||
assertTrue(recyclerContainsText(list, "收起"));
|
||||
assertTrue(recyclerContainsText(list, "主 Agent"));
|
||||
assertTrue(recyclerContainsText(list, "Boss 移动控制台"));
|
||||
|
||||
View pinnedHeader = content.getChildAt(1);
|
||||
View pinnedHeader = getRecyclerChild(list, 1);
|
||||
pinnedHeader.performClick();
|
||||
|
||||
assertEquals(true, ReflectionHelpers.getField(activity, "pinnedConversationsCollapsed"));
|
||||
assertTrue(viewTreeContainsText(content, "展开"));
|
||||
assertTrue("收起后普通会话仍应保留", viewTreeContainsText(content, "Boss 移动控制台"));
|
||||
assertTrue(recyclerContainsText(list, "展开"));
|
||||
assertTrue("收起后普通会话仍应保留", recyclerContainsText(list, "Boss 移动控制台"));
|
||||
}
|
||||
|
||||
private static View getRecyclerChild(RecyclerView recyclerView, int position) {
|
||||
RecyclerView.Adapter adapter = recyclerView.getAdapter();
|
||||
int viewType = adapter.getItemViewType(position);
|
||||
RecyclerView.ViewHolder holder = adapter.createViewHolder(recyclerView, viewType);
|
||||
adapter.bindViewHolder(holder, position);
|
||||
FrameLayout container = (FrameLayout) holder.itemView;
|
||||
return container.getChildAt(0);
|
||||
}
|
||||
|
||||
private static boolean recyclerContainsText(RecyclerView recyclerView, String expectedText) {
|
||||
RecyclerView.Adapter adapter = recyclerView.getAdapter();
|
||||
for (int index = 0; index < adapter.getItemCount(); index += 1) {
|
||||
if (viewTreeContainsText(getRecyclerChild(recyclerView, index), expectedText)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean viewTreeContainsText(View root, String expectedText) {
|
||||
|
||||
Reference in New Issue
Block a user