pow*_*366 7 android android-layout android-fragments wear-os
我在我的Android Wear圆形手表(在正方形上工作)上获得黑屏.两种布局在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);
...
Run Code Online (Sandbox Code Playgroud)
布局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>
Run Code Online (Sandbox Code Playgroud)
从以下地方拨打电话:
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;
}
...
Run Code Online (Sandbox Code Playgroud)
这是从:
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);
}
});
}
...
Run Code Online (Sandbox Code Playgroud)
有没有人看过这个或者可以给我一个如何解决它的提示?
更新:
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>
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
额外信息:
public class ScrollableGridViewPager extends GridViewPager {
...
Run Code Online (Sandbox Code Playgroud)

Mac*_*ęga 11
问题不是那么微不足道,所以我希望我已经很清楚地描述了它.
这个问题的真正原因是该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
Run Code Online (Sandbox Code Playgroud)
但在此之后,第二次调用此方法是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
Run Code Online (Sandbox Code Playgroud)
我不知道这个问题是仅在模拟器上还是在真实设备上发生,但我认为这应该被报告为wearable-support-lib中的一个错误(在WatchViewStub组件中要准确).任何地方都没有记录这种行为.
上面的问题听起来应该什么都不做......新的布局是膨胀的(所以旧的布局被删除),新的MenuAdapter将被创建(旧的将不再被使用,所以谁关心),这个新创建MenuAdapter应该被设置为新的适配器GridViewPager.一切都应该"重置"所以它应该仍然可以正常工作(除了由于布局膨胀两次而不是一次膨胀的性能问题).
不完全是......因为这是棘手的部分GridViewPager.
我不知道确切的源代码GridViewPager和FragmentGridPagerAdapter,但它似乎是相似ViewPager和FragmentPagerAdapter代码.FragmentPagerAdapter增加了新创建的片段的FragmentManager特别tag是由具有id的的ViewPager给孩子片段和位置:
122 private static String More ...makeFragmentName(int viewId, int index) {
123 return "android:switcher:" + viewId + ":" + index;
124 }
Run Code Online (Sandbox Code Playgroud)
一旦片段被添加到FragmentManager(当前Activity)tag中,将来可以通过此名称引用它.真正的问题是由于onLayoutInflated(WatchViewStub)方法被调用两次而引起的.第一个片段首先创建MenuAdapter并添加到具有id R.id.pager(来自rect_activity.xml)的容器中.然后round_activity.xml膨胀并调用第二个onLayoutInflated(WatchViewStub)调用 - 新的片段在new中创建MenuAdapter并添加到新膨胀GridViewPager的相同id : R.id.pager. 所以第一个片段和第二个想拥有完全相同的tag在FragmentManager.
在标准中,FragmentPagerAdapter如果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 }
Run Code Online (Sandbox Code Playgroud)
所以可能情况类似,并且第一个片段被重用,它被添加到GridViewPager带有id 的第一个片段R.id.pager- 但是这个片段不再存在,所以片段不能附加到任何地方(并显示).这是一个实现的东西,只有一个ViewPager像父亲一样具有给定的id Activity.
对于另外一个实验,我为两者设置了不同的ID GridViewPagers.一个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);
}
}
});
Run Code Online (Sandbox Code Playgroud)
仅在第一次传递gridViewPager1中找到并且仅设置其适配器.类似于第二次传递 - 仅gridViewPager2设置了适配器.因为GridViewPagers具有不同的id tags,所以片段中没有冲突,因此最终结果如预期的那样.
但这只是为了证明上面描述的理论:)

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);
}
}
Run Code Online (Sandbox Code Playgroud)
这将使您的示例完美无需使用WatchViewStub.
| 归档时间: |
|
| 查看次数: |
3100 次 |
| 最近记录: |