gpt4 book ai didi

android - 圆形 fragment 在模拟器/ watch 中佩戴 watch 变黑

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:21:29 24 4
gpt4 key购买 nike

我在我的 Android Wear 圆形 watch 上出现黑屏(在方形上它可以工作)。
两种布局在 Android Studio 布局设计中都显示正常。

要测试的项目:

https://bitbucket.org/powder366/motoblack

我使用以下代码:

public class MyFragment extends Fragment {
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View contentView = inflater.inflate(R.layout.my_fragment, container, false);
...

布局 my_fragment:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/my_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:keepScreenOn="true"
tools:context=".WearFragment">

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">

<TextView
android:id="@+id/text1"
android:text="Hi1"
android:layout_gravity="center_horizontal"
style="@style/UnitsStyle"/>

<TextView
android:id="@+id/text2"
android:text="Hi2"
android:layout_gravity="center_horizontal"
style="@style/BaseStyle"/>

<TextView
android:id="@+id/text3"
android:text="Hi3"
android:layout_gravity="center_horizontal"
style="@style/UnitsStyle"/>

</LinearLayout>

</LinearLayout>

从以下位置调用它:
public class MenuAdapter extends FragmentGridPagerAdapter
...
public MenuAdapter(Context context, FragmentManager fm, Handler handler) {
super(fm);
mContext = context;
mHandler = handler;
myFragment = new MyFragment();
}
...
@Override
public Fragment getFragment(int rowNum, int colNum) {
Log.d(TAG, String.format("getFragment(%d, %d)", rowNum, colNum));

if(colNum == 0) {
return myFragment;
}

if(colNum == 1) {
final SecondFragment switchAction = SecondFragment.newInstance(mHandler);
return switchAction;
}

return null;
}
...

从以下位置调用:
public class WearActivity extends Activity {
...

private GridViewPager gridViewPager;
private MenuAdapter menuAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "Create(Wear)");
super.onCreate(savedInstanceState);
setContentView(R.layout.wear_activity);

final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
@Override
public void onLayoutInflated(WatchViewStub stub) {
menuAdapter = new MenuAdapter(WearActivity.this, getFragmentManager(), mHandler);
gridViewPager = (GridViewPager) findViewById(R.id.pager);
gridViewPager.setAdapter(menuAdapter);
}
});
}
...

有没有人看到这个或者可以给我一个关于如何解决它的提示?

更新:

wear_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.WatchViewStub
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/watch_view_stub"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:rectLayout="@layout/rect_activity"
app:roundLayout="@layout/round_activity"
tools:context=".WearActivity"
tools:deviceIds="wear">
</android.support.wearable.view.WatchViewStub>

rect_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
tools:deviceIds="wear_square">

<com.xyz.my.ScrollableGridViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"/>

</FrameLayout>

round_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
tools:deviceIds="wear_round">

<com.xyz.my.ScrollableGridViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"/>

</FrameLayout>

额外信息:
public class ScrollableGridViewPager extends GridViewPager {
...

enter image description here
enter image description here

最佳答案

这个问题不是那么小,所以我希望我已经描述得很清楚了。

原因1:

这个问题的真正原因是 onLayoutInflated(WatchViewStub)方法是两次调用在圆形设备上。

第一次调用 rect_activity.xml膨胀:

WearActivity$1.onLayoutInflated(WatchViewStub) line: 26 
WatchViewStub.inflate() line: 133
WatchViewStub.onMeasure(int, int) line: 141
WatchViewStub(View).measure(int, int) line: 16648

但在那之后,第二次调用这个方法是用新膨胀的 round_activity.xml 完成的。当 onApplyWindowInsets(WindowInsets)被派出:
WearActivity$1.onLayoutInflated(WatchViewStub) line: 26 
WatchViewStub.inflate() line: 133
WatchViewStub.onApplyWindowInsets(WindowInsets) line: 112
WatchViewStub(View).dispatchApplyWindowInsets(WindowInsets) line: 6051
WatchViewStub(ViewGroup).dispatchApplyWindowInsets(WindowInsets) line: 5435
SwipeDismissLayout(ViewGroup).dispatchApplyWindowInsets(WindowInsets) line: 5439
PhoneWindow$DecorView(ViewGroup).dispatchApplyWindowInsets(WindowInsets) line: 5439
ViewRootImpl.dispatchApplyInsets(View) line: 1170

我不知道这个问题是只发生在模拟器上还是真实设备上,但我认为这应该报告为 wearable-support-lib 中的错误(准确地说是在 WatchViewStub 组件中)。这种行为在任何地方都没有记录。

原因 #2(#1 的视觉后果):

上面的问题听起来应该什么都不做......新的布局被夸大了(所以旧的被删除了),新的 MenuAdapter将被创建(旧的将不再使用,所以谁在乎),而这个新创建的 MenuAdapter应该在新的 GridViewPager 中设置为适配器.一切都应该“重置”,所以它应该仍然可以正常工作(除了由于布局膨胀两次而不是一次而导致的性能问题)。

不完全是……因为这是 GridViewPager 的棘手部分.

我不知道 GridViewPager 的确切源代码和 FragmentGridPagerAdapter但它似乎类似于 ViewPagerFragmentPagerAdapter代码。 FragmentPagerAdapter将新创建的 fragment 添加到 FragmentManager带特殊 tagid 组成的 ViewPager和给定子 fragment 的位置:
122    private static String More ...makeFragmentName(int viewId, int index) {
123 return "android:switcher:" + viewId + ":" + index;
124 }

一旦将 fragment 添加到 FragmentManager (在当前 Activity 中)可以通过此 tag 引用将来的名字。
真正的问题是由 onLayoutInflated(WatchViewStub) 引起的。方法被调用两次。第一个 fragment 是在第一个 MenuAdapter 中创建的并添加到 ID 为 R.id.pager 的容器中(来自 rect_activity.xml)。然后 round_activity.xml被夸大了,第二次调用 onLayoutInflated(WatchViewStub)被调用 - 在新的 MenuAdapter 中创建新 fragment 并添加到新膨胀的 GridViewPager具有相同 ID: R.id.pager .所以第一个 fragment 和第二个 fragment 想要完全相同 tagFragmentManager .

在标准 FragmentPagerAdapter如果 fragment 具有给定 tag已存在于 FragmentManager 中它再次附加到它的前一个父级。您可以在此处查看源代码:
50     @Override
51 public Object More ...instantiateItem(View container, int position) {
52 if (mCurTransaction == null) {
53 mCurTransaction = mFragmentManager.beginTransaction();
54 }
55
56 // Do we already have this fragment?
57 String name = makeFragmentName(container.getId(), position);
58 Fragment fragment = mFragmentManager.findFragmentByTag(name);
59 if (fragment != null) {
60 if (DEBUG) Log.v(TAG, "Attaching item #" + position + ": f=" + fragment);
61 mCurTransaction.attach(fragment);
62 } else {
63 fragment = getItem(position);
64 if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment);
65 mCurTransaction.add(container.getId(), fragment,
66 makeFragmentName(container.getId(), position));
67 }
68 if (fragment != mCurrentPrimaryItem) {
69 fragment.setMenuVisibility(false);
70 }
71
72 return fragment;
73 }

所以大概情况差不多,第一个fragment被复用了,加到第一个 GridViewPager编号为 R.id.pager - 但是这个父级不再存在,所以 fragment 不能附加到任何地方(并被显示)。这是实现的东西,只能有一个 ViewPager - 类似 parent ,在一个 Activity 中具有给定的 ID .

对于另一个实验,我为 GridViewPagers 设置了不同的 ID。 .一个与 rect_activity.xml有 ID R.id.pager1另一个在 round_activity.xml有`R.id.pager2'。
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
@Override
public void onLayoutInflated(WatchViewStub stub) {
menuAdapter = new MenuAdapter(WearActivity.this, getFragmentManager());
GridViewPager gridViewPager1 = (GridViewPager) findViewById(R.id.pager1);
if(gridViewPager1!=null) { // rect_activity
gridViewPager1.setAdapter(menuAdapter);
}

GridViewPager gridViewPager2 = (GridViewPager) findViewById(R.id.pager2);
if(gridViewPager2!=null) { // round_activity
gridViewPager2.setAdapter(menuAdapter);
}
}
});

仅在第一次通过 gridViewPager1找到并且只设置了它的适配器。在第二遍中类似 - 仅适用于 gridViewPager2 的适配器已设置。
因为 GridViewPagers有不同的 id 在 fragment tags 中没有冲突,所以最终结果如预期。
但这只是为了证明上述理论:)

enter image description here

解决方案:
WatchViewStub用于为 rect 提供不同的布局和 round屏幕。我可以看到您对两种形状使用完全相同的布局。您可以摆脱 WatchViewStub并这样做:
public class WearActivity extends Activity {

private GridViewPager gridViewPager;
private MenuAdapter menuAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rect_activity);

menuAdapter = new MenuAdapter(WearActivity.this, getFragmentManager());
gridViewPager = (GridViewPager) findViewById(R.id.pager);
gridViewPager.setAdapter(menuAdapter);
}
}

这将使您的示例在不使用 WatchViewStub 的情况下完美运行.

关于android - 圆形 fragment 在模拟器/ watch 中佩戴 watch 变黑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25808229/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com