Collapsing/Expanding 视图与滑动 RecyclerView 协调
Collapsing/Expanding view coordinated with Sliding RecyclerView
我正在尝试实现以下效果(另见下图):
- 应用程序打开时,视图(地图)部分可见,
RecyclerView
在默认锚点(中心图像)
- 用户向上滚动
RecyclerView
,地图折叠,列表继续滚动(右图)
- 用户向下滚动
RecyclerView
,地图扩展到最大点(注意列表不应完全滑出屏幕,而是滑到某个锚点)(左图)
要创建它,我们需要 1 Activity
和 3 Fragment
s。
Activity
将托管一个 TabLayout
和一个 ViewPager
,如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
因为我们只需要为第一个 Fragment
执行滑动行为,第一个 Fragment
得到一个 XML 布局,如下所示:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="400dp"
android:orientation="vertical"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsingToolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<com.google.android.gms.maps.MapView
android:id="@+id/mapView"
app:layout_collapseMode="parallax"
android:layout_height="400dp"
android:layout_width="match_parent" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
您可以根据自己的喜好制作其他 Fragment
我只是在其他 Fragment
中创建了假数据和一个简单的 RecyclerView
。
然后在您的 Activity
和 Fragment
中调用这些视图,如下所示:
Activity
public class MainActivity extends AppCompatActivity {
private TabLayout mTabLayout;
private ViewPager mViewPager;
private SampleViewPagerAdapter mViewPagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.another_activity);
mTabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mViewPagerAdapter = new SampleViewPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mViewPagerAdapter);
mTabLayout.setupWithViewPager(mViewPager);
}
}
ViewPager 适配器
public class SampleViewPagerAdapter extends FragmentPagerAdapter {
public SampleViewPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new MapFragment();
case 1:
return new ScrollFragment();
case 2:
return new ScrollFragment();
default:
return new ScrollFragment();
}
}
@Override
public int getCount() {
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
String[] tabNames = {"Stops", "Planner", "Alerts"};
return tabNames[position];
}
}
带有滑动 RecyclerView 的地图片段
public class MapFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.activity_main, null);
initCollapsingToolbar(root);
// Initialize map
initFragment();
return root;
}
private void initCollapsingToolbar(View root) {
CollapsingToolbarLayout collapsingToolbarLayout =
(CollapsingToolbarLayout) root.findViewById(R.id.collapsingToolbar);
collapsingToolbarLayout.setContentScrimColor(getResources().getColor(R.color.cyan_500));
}
private void initFragment() {
FakeDataFragment fragment = new FakeDataFragment();
getChildFragmentManager().beginTransaction()
.replace(R.id.content, scrollFragment)
.commit();
}
}
那你应该得到这样的东西:
设置位置:
您可以使用以下代码以编程方式折叠工具栏 (CollapsingToolbarLayout
):
public void collapseToolbar(){
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) mFrameLayout.getLayoutParams();
AppBarLayout.ScrollingViewBehavior behavior = (AppBarLayout.ScrollingViewBehavior) params.getBehavior();
if (behavior != null) {
behavior.onNestedFling(rootLayout, appbarLayout, null, 0, 10000, true);
}
}
这意味着当用户第一次看到地图时,地图会部分折叠到您的默认状态。
我在 CoordinatorLayout 中找到了选项卡的解决方案
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/htab_maincontent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/htab_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/htab_collapse_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|enterAlways|snap"
app:statusBarScrim="@null"
app:titleEnabled="false">
<LinearLayout
android:id="@+id/isprofile"
android:layout_width="match_parent"
android:layout_height="180dp"
android:background="@drawable/profile_cover"
android:gravity="center"
app:layout_collapseMode="parallax">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="10dp"
android:gravity="center"
android:orientation="vertical">
<com.root.findagame.utills.CircleImageView
android:id="@+id/profile_pic"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/profile_pic" />
<TextView
android:id="@+id/txtUserName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textColor="@color/cpb_white"
android:textSize="@dimen/text_medium_size"
android:textStyle="bold" />
<TextView
android:id="@+id/txtAge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text=""
android:textColor="@color/cpb_white"
android:textSize="@dimen/text_small_size" />
<TextView
android:id="@+id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text=""
android:textColor="@color/cpb_white"
android:textSize="@dimen/text_small_size"
android:visibility="gone" />
</LinearLayout>
</LinearLayout>
<android.support.v7.widget.Toolbar
android:id="@+id/htab_toolbar"
android:layout_width="match_parent"
android:layout_height="40dp"
android:visibility="gone"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.CollapsingToolbarLayout>
<android.support.design.widget.TabLayout
android:id="@+id/htab_tabs"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_gravity="bottom"
android:background="@color/cpb_white"
app:layout_collapseMode="pin"
app:tabIndicatorColor="#7CC142"
app:tabSelectedTextColor="#7CC142"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:tabTextAppearance="@android:style/TextAppearance.Widget.TabWidget"
app:tabTextColor="@color/lightGrayColor" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/htab_viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
*Fragment*
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dummyfrag_bg"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/dummyfrag_scrollableview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false" />
</FrameLayout>
我正在尝试实现以下效果(另见下图):
- 应用程序打开时,视图(地图)部分可见,
RecyclerView
在默认锚点(中心图像) - 用户向上滚动
RecyclerView
,地图折叠,列表继续滚动(右图) - 用户向下滚动
RecyclerView
,地图扩展到最大点(注意列表不应完全滑出屏幕,而是滑到某个锚点)(左图)
要创建它,我们需要 1 Activity
和 3 Fragment
s。
Activity
将托管一个 TabLayout
和一个 ViewPager
,如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
因为我们只需要为第一个 Fragment
执行滑动行为,第一个 Fragment
得到一个 XML 布局,如下所示:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="400dp"
android:orientation="vertical"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsingToolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<com.google.android.gms.maps.MapView
android:id="@+id/mapView"
app:layout_collapseMode="parallax"
android:layout_height="400dp"
android:layout_width="match_parent" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
您可以根据自己的喜好制作其他 Fragment
我只是在其他 Fragment
中创建了假数据和一个简单的 RecyclerView
。
然后在您的 Activity
和 Fragment
中调用这些视图,如下所示:
Activity
public class MainActivity extends AppCompatActivity {
private TabLayout mTabLayout;
private ViewPager mViewPager;
private SampleViewPagerAdapter mViewPagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.another_activity);
mTabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mViewPagerAdapter = new SampleViewPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mViewPagerAdapter);
mTabLayout.setupWithViewPager(mViewPager);
}
}
ViewPager 适配器
public class SampleViewPagerAdapter extends FragmentPagerAdapter {
public SampleViewPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new MapFragment();
case 1:
return new ScrollFragment();
case 2:
return new ScrollFragment();
default:
return new ScrollFragment();
}
}
@Override
public int getCount() {
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
String[] tabNames = {"Stops", "Planner", "Alerts"};
return tabNames[position];
}
}
带有滑动 RecyclerView 的地图片段
public class MapFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.activity_main, null);
initCollapsingToolbar(root);
// Initialize map
initFragment();
return root;
}
private void initCollapsingToolbar(View root) {
CollapsingToolbarLayout collapsingToolbarLayout =
(CollapsingToolbarLayout) root.findViewById(R.id.collapsingToolbar);
collapsingToolbarLayout.setContentScrimColor(getResources().getColor(R.color.cyan_500));
}
private void initFragment() {
FakeDataFragment fragment = new FakeDataFragment();
getChildFragmentManager().beginTransaction()
.replace(R.id.content, scrollFragment)
.commit();
}
}
那你应该得到这样的东西:
设置位置:
您可以使用以下代码以编程方式折叠工具栏 (CollapsingToolbarLayout
):
public void collapseToolbar(){
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) mFrameLayout.getLayoutParams();
AppBarLayout.ScrollingViewBehavior behavior = (AppBarLayout.ScrollingViewBehavior) params.getBehavior();
if (behavior != null) {
behavior.onNestedFling(rootLayout, appbarLayout, null, 0, 10000, true);
}
}
这意味着当用户第一次看到地图时,地图会部分折叠到您的默认状态。
我在 CoordinatorLayout 中找到了选项卡的解决方案
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/htab_maincontent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/htab_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/htab_collapse_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|enterAlways|snap"
app:statusBarScrim="@null"
app:titleEnabled="false">
<LinearLayout
android:id="@+id/isprofile"
android:layout_width="match_parent"
android:layout_height="180dp"
android:background="@drawable/profile_cover"
android:gravity="center"
app:layout_collapseMode="parallax">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="10dp"
android:gravity="center"
android:orientation="vertical">
<com.root.findagame.utills.CircleImageView
android:id="@+id/profile_pic"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/profile_pic" />
<TextView
android:id="@+id/txtUserName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textColor="@color/cpb_white"
android:textSize="@dimen/text_medium_size"
android:textStyle="bold" />
<TextView
android:id="@+id/txtAge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text=""
android:textColor="@color/cpb_white"
android:textSize="@dimen/text_small_size" />
<TextView
android:id="@+id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text=""
android:textColor="@color/cpb_white"
android:textSize="@dimen/text_small_size"
android:visibility="gone" />
</LinearLayout>
</LinearLayout>
<android.support.v7.widget.Toolbar
android:id="@+id/htab_toolbar"
android:layout_width="match_parent"
android:layout_height="40dp"
android:visibility="gone"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.CollapsingToolbarLayout>
<android.support.design.widget.TabLayout
android:id="@+id/htab_tabs"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_gravity="bottom"
android:background="@color/cpb_white"
app:layout_collapseMode="pin"
app:tabIndicatorColor="#7CC142"
app:tabSelectedTextColor="#7CC142"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:tabTextAppearance="@android:style/TextAppearance.Widget.TabWidget"
app:tabTextColor="@color/lightGrayColor" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/htab_viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
*Fragment*
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dummyfrag_bg"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/dummyfrag_scrollableview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false" />
</FrameLayout>