ViewPager
最初は正しくレイアウトされる を含むレイアウトがありますが、再構築時にデバイスを回転させるとViewPager
崩壊します。RelativeLayout と LinearLayout の両方で試してみましたが、どちらの場合も同じ結果になりました。ここに私の LinearLayout バージョンがあります:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/fullPlayer"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="@style/AppTheme.Player"
android:clickable="true"
android:animateLayoutChanges="true"
tools:context="com.xxx.music.fragment.PlayerFragment">
<RelativeLayout
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp">
<android.support.v4.view.ViewPager
android:id="@+id/albumPager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/playerQueueList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
style="@style/AppTheme.Queue"
/>
<RelativeLayout
style="@style/AppTheme.ActionBar.Transparent"
android:layout_alignParentTop="true"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize">
<ImageButton android:id="@+id/playerToggle"
style="@style/Widget.AppCompat.Button.Borderless"
app:srcCompat="@drawable/ic_arrow_back_white_24dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
<ImageButton
android:id="@+id/playerMenu"
style="@style/Widget.AppCompat.Button.Borderless"
app:srcCompat="@drawable/ic_more_vert_white_24dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"/>
<TextView
android:id="@+id/playerTitle"
style="@style/TextAppearance.AppCompat.Title.Inverse"
android:visibility="invisible"
android:layout_toRightOf="@id/playerToggle"
android:layout_toLeftOf="@id/playerMenu"
android:layout_centerVertical="true"
android:text="@string/playerQueue"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
</RelativeLayout>
<LinearLayout android:id="@+id/songInfoHeader"
android:orientation="vertical"
android:paddingLeft="16dip"
android:paddingRight="16dip"
android:paddingTop="@dimen/default_gap"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/songTitleView"
style="@style/AppTheme.SongTitle"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:layout_height="wrap_content"
android:layout_width="wrap_content"/>
<TextView android:id="@+id/songArtistView"
style="@style/AppTheme.SongArtist"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView android:id="@+id/songAlbumView"
style="@style/AppTheme.SongAlbum"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/default_gap"
android:paddingBottom="@dimen/default_gap"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/songPositionView"
style="@style/AppTheme.SongAlbum"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Space
android:layout_width="@dimen/default_gap"
android:layout_height="wrap_content" />
<SeekBar android:id="@+id/songProgressView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:indeterminate="false"
android:indeterminateBehavior="repeat"
android:layout_gravity="fill_horizontal"/>
<Space
android:layout_width="@dimen/default_gap"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/songDurationView"
style="@style/AppTheme.SongAlbum"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout android:id="@+id/playerFooter"
android:orientation="horizontal"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:layout_marginTop="@dimen/default_gap"
android:layout_marginBottom="@dimen/default_gap"
android:gravity="center_horizontal">
<ImageButton android:id="@+id/playQueueButton"
android:scaleType="fitXY"
android:layout_height="24dp"
android:layout_width="24dp"
android:layout_gravity="center_vertical"
style="@style/AppTheme.Button.Flat.Inverse"
app:srcCompat="@drawable/ic_queue_music_white_24dp"/>
<Space
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<ImageButton android:id="@+id/prevTrackButton"
android:scaleType="fitXY"
android:layout_height="48dp"
android:layout_width="48dp"
android:layout_gravity="center_vertical"
style="@style/AppTheme.Button.Flat.Inverse"
app:srcCompat="@drawable/ic_skip_previous_white_24dp"/>
<Space
android:layout_width="20dp"
android:layout_height="match_parent" />
<ImageButton android:id="@+id/playButton"
android:scaleType="fitXY"
android:layout_height="72dp"
android:layout_width="72dp"
android:layout_gravity="center_vertical"
style="@style/AppTheme.Button.Flat.Inverse"
app:srcCompat="@drawable/ic_play_circle_outline_white_24px"/>
<Space
android:layout_width="20dp"
android:layout_height="match_parent" />
<ImageButton android:id="@+id/nextTrackButton"
android:scaleType="fitXY"
android:layout_height="48dp"
android:layout_width="48dp"
android:layout_gravity="center_vertical"
style="@style/AppTheme.Button.Flat.Inverse"
app:srcCompat="@drawable/ic_skip_next_white_24dp"/>
<Space
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<ImageButton android:id="@+id/shuffleTrackButton"
android:scaleType="fitXY"
android:layout_height="24dp"
android:layout_width="24dp"
android:layout_gravity="center_vertical"
style="@style/AppTheme.Button.Flat.Inverse"
app:srcCompat="@drawable/ic_shuffle_white_24dp"/>
</LinearLayout>
</LinearLayout>
RelativeLayout を top として使用するバージョンがViewGroup
ありますが、まったく同じ動作をします。
いくつかの回避策を試しました。ビューが作成された後にこのメソッドを使用しています。
protected void requestLayoutBugFix() {
// this is here because bottom sheet library has a bug which will
// cause layouts to not update when they are complicated
final View v = getView();
if( v != null ) {
Ln.i("Request Layout to fix bugs");
v.requestLayout();
}
}
しかし、それはそれに影響していないようです。BottomSheet を折りたたんで展開すると、それはそれを修正します。ページには別のビュー (再生キュー) もあり、再生キューとアルバム画像を切り替えると正しく描画されます。だから私はそれがアニメーションとBottomSheetに関係していると思います.
プレーヤーを折りたたむ/展開するために使用するコードは次のとおりです。
public void expandPlayer() {
Ln.i("Expand Player");
albumPager.setVisibility(View.VISIBLE);
playerQueueList.setVisibility(View.GONE);
playerUI.setHideable(false);
playerUI.setState(BottomSheetBehavior.STATE_EXPANDED);
fullPlayer.startAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.fade_in));
miniPlayer.startAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.fade_out));
playerQueueVisible = false;
}
public void collapsePlayer() {
Ln.i("Collapse Player");
playerUI.setHideable(false);
playerUI.setState(BottomSheetBehavior.STATE_COLLAPSED);
fullPlayer.startAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.fade_out));
miniPlayer.startAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.fade_in));
}
PageAdapter に使用されるコード:
private class AlbumPageAdapter extends FragmentStatePagerAdapter {
List<Track> tracks;
public AlbumPageAdapter(FragmentManager fm) {
super(fm);
tracks = new ArrayList<Track>();
refresh();
}
@Override
public int getCount() {
return tracks.size();
}
@Override
public Fragment getItem(int position) {
Track track = tracks.get(position);
return ImageSetFragment.newInstance(track);
}
public void refresh() {
tracks.clear();
tracks.addAll( player.getQueue() );
notifyDataSetChanged();
}
@Override
public int getItemPosition(Object object) {
// refresh all fragments when data set changed
return PagerAdapter.POSITION_NONE;
}
}
イメージ セット フラグメント:
public class ImageSetFragment extends EnhancedRoboFragment {
private static final String IMAGE_SET = "IMAGE_SET";
private ImageSet imageSet;
private ImageView mImageView;
public ImageSetFragment() {}
public static ImageSetFragment newInstance(ImageSet imageSet) {
final ImageSetFragment f = new ImageSetFragment();
final Bundle args = new Bundle();
args.putStringArray(IMAGE_SET, new String[] { imageSet.getImageLarge().toString(), imageSet.getImageNormal().toString(), imageSet.getImageMedium().toString() } );
f.setArguments(args);
return f;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
imageSet = getArguments() != null ? new SimpleImageSet( getArguments().getStringArray(IMAGE_SET) ) : null;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.player_image, container, false);
mImageView = (ImageView) v.findViewById(R.id.imageView);
return v;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Rect insets = new Rect( 25, 25, 25, 25);
LayoutUtil.loadImage( getActivity(), mImageView, new BlurredBgHDTransformation(mImageView.getContext(), insets), imageSet);
mImageView.setPadding(3, 3, 3, 3);
}
}
更新: ViewPager を ImageView に置き換えようとしました。ImageView が描画されなかったという点で同じ動作です。ViewPager がレンダリングされるため、実際には少し悪化しましたが、ヘッダーの高さまでしか表示されないため、ViewPager の上部は表示されますが、その後は何も表示されません。それを ImageView に置き換えたところ、電話を回転させたときに ImageView の一部がレンダリングされませんでした。