问题描述
当我尝试触摸AppBarLayout部件进行滚动时,我遇到了滚动折叠AppBar的问题.而且有时滚动也不流畅.
I have an issue with scrolling Collapsing AppBar, when I am trying to scroll it touching the AppBarLayout part. And also it sometimes scrolling not smoothly.
此处是发行的简短视频(1m 30s): https://www.youtube.com/watch?v=n32N9Z4S3SA&feature=youtu.be
此处是指向简单项目的链接(仅在github上存在此问题): https://github.com/yozhik/Reviews/tree/master/app/src/main/java/com/ylet/sr/review
我正在使用: com.android.support:appcompat-v7:27.1.1
场外存在问题: https://issuetracker.google.com/issues/37050152
情况如何: https://www.youtube.com/观看?v = xWadOVEaTSY& feature = youtu.be
应如何设置: https://www.youtube.com/watch?v=J8ITp6RusZo&feature=youtu.be
有人知道如何解决您在视频中看到的此问题吗?我创建了绝对简单的布局来避免任何副作用,但是仍然复制了错误.预先感谢.
Does anybody know how to fix this issue you saw on video? I created absolutely simple layouts to avoid any side effects, but bug still reproduced. Thanks in advance.
说明:
CollapsingActivity
-与Collapsing AppBarLayout
一起活动.将一个或两个片段加载到"fragment_content_holder
"中,并且具有TabLayout
在视图分页器中的片段之间切换.
CollapsingActivity
- activity with Collapsing AppBarLayout
. Which loads one or two fragments into "fragment_content_holder
" and it has TabLayout
to switch between fragments in view pager.
在活动方法onCreate()
中-我只是模拟对服务器(loadData
)的请求,并且当加载了一些虚假数据时-我在第一次调用时在视图寻呼机中显示片段-我正在创建新的扩展FragmentPagerAdapter
,用片段填充它并保存到实例的链接.在下一个电话上-我不会从头开始创建片段,而只是用新数据填充它们.
In activity method onCreate()
- I'm just simulating request to server (loadData
), and when some fake data is loaded - I am showing fragments in view pager, on first call - I am creating new TabMenuAdapter
extends FragmentPagerAdapter
, populate it with fragments and save links to instances. On the next call -I don't create fragments from scratch and just populate them with fresh data.
MenuFragment1, MenuFragment1
-两个片段.MenuFragment1
-具有方法public void setupData(SomeCustomData data)
,用于设置新数据,而不是在网络重新连接时重新创建片段.
MenuFragment1, MenuFragment1
- two fragments.MenuFragment1
- has method public void setupData(SomeCustomData data)
, to set new data, not recreating fragment on network reconnect.
NetworkStateReceiver
-监听网络变化并发送通知.
NetworkStateReceiver
- listens to network change and send notifications.
TabMenuAdapter
-只是保存片段的简单类.
TabMenuAdapter
- just simple class to hold fragments.
接下来就是复制/粘贴代码:
Next is just copy/paste of code:
public class CollapsingActivity extends AppCompatActivity implements ChangeNetworkNotification {
private static int dataReloadIteration = 0;
private SomeCustomData dummyDataFromServer;
@BindView(R.id.root_layout)
CoordinatorLayout root_layout;
@BindView(R.id.app_bar_layout)
AppBarLayout app_bar_layout;
@BindView(R.id.collapsing_toolbar_layout)
CollapsingToolbarLayout collapsing_toolbar_layout;
@BindView(R.id.view_pager_layout)
ViewPager viewPager;
@BindView(R.id.tab_layout)
TabLayout tabLayout;
@BindView(R.id.collapsing_data_1_txt)
TextView collapsing_data_1_txt;
private NetworkStateReceiver networkStateReceiver;
private boolean isConnected;
protected Fragment currentFragment;
protected Fragment previousFragment;
protected FragmentManager fragmentManager;
private boolean dataLoading = false;
private boolean isCreated = false;
private MenuFragment1 menu1Fragment1;
private MenuFragment2 menu1Fragment2;
private TabMenuAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d("TEST", "CollapsingActivity.onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_collapsing);
ButterKnife.bind(this);
fragmentManager = getSupportFragmentManager();
networkStateReceiver = new NetworkStateReceiver();
networkStateReceiver.setNetworkReceiver(this);
IntentFilter intentFilterForNetwork = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(networkStateReceiver, intentFilterForNetwork);
initToolbar();
loadData();
}
@Override
protected void onStart() {
Log.d("TEST", "CollapsingActivity.onStart");
super.onStart();
IntentFilter intentFilterForNetwork = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(networkStateReceiver, intentFilterForNetwork);
}
private void initToolbar() {
Log.d("TEST", "CollapsingActivity.initToolbar");
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_layout);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
private void loadData() {
Log.d("TEST", "CollapsingActivity.loadData");
dataLoading = true;
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(CollapsingActivity.this, "Data loaded.", Toast.LENGTH_SHORT).show();
Log.d("TEST", "CollapsingActivity.Data loaded.");
dataReloadIteration++;
dummyDataFromServer = getDummyObjectFromServer();
collapsing_data_1_txt.setText(dummyDataFromServer.Name); //Set data from server in collapsing part of Activity
boolean showOneView = false;
if (showOneView) {
initSingleView();
} else {
if (!isCreated) {
initTabView();
} else {
menu1Fragment1.setupData(dummyDataFromServer); //Set the data from server to fragment, not reloading it, just updating data
}
}
dataLoading = false;
}
});
}
});
t.start();
}
private SomeCustomData getDummyObjectFromServer() {
SomeCustomData dto = new SomeCustomData();
dto.Age = dataReloadIteration;
dto.Name = "Name " + dataReloadIteration;
return dto;
}
private void initSingleView() {
Log.d("TEST", "CollapsingActivity.initSingleView");
tabLayout.setVisibility(View.GONE);
viewPager.setVisibility(View.GONE);
showFragmentWithoutBackStack(R.id.fragment_content_holder, new MenuFragment1());
}
private void initTabView() {
if (!isCreated) {
Log.d("TEST", "CollapsingActivity.initTabView");
tabLayout.setVisibility(View.VISIBLE);
viewPager.setVisibility(View.VISIBLE);
setupViewPager(viewPager);
tabLayout.setupWithViewPager(viewPager);
isCreated = true;
}
}
private void setupViewPager(ViewPager viewPager) {
Log.d("TEST", "CollapsingActivity.setupViewPager");
menu1Fragment1 = MenuFragment1.newInstance(dummyDataFromServer);
menu1Fragment2 = MenuFragment2.newInstance();
adapter = new TabMenuAdapter(getSupportFragmentManager());
adapter.addFragment(menu1Fragment1, "Menu 1");
adapter.addFragment(menu1Fragment2, "Menu 2");
viewPager.setAdapter(adapter);
}
@Override
protected void onDestroy() {
Log.d("TEST", "CollapsingActivity.onDestroy");
super.onDestroy();
unregisterReceiver(networkStateReceiver);
}
@Override
public void networkStateIsChanged(boolean isConnected) {
this.isConnected = isConnected;
Log.d("TEST", "CollapsingActivity.networkStateIsChanged.isConnected: " + isConnected);
if (isConnected) {
Toast.makeText(CollapsingActivity.this, "Connection received.", Toast.LENGTH_SHORT).show();
if (!dataLoading) {
loadData();
}
} else {
Toast.makeText(CollapsingActivity.this, "Connection lost.", Toast.LENGTH_SHORT).show();
}
}
protected void showFragmentWithoutBackStack(int containerViewId, Fragment fragment) {
Log.d("TEST", "CollapsingActivity.showFragmentWithoutBackStack");
previousFragment = currentFragment;
currentFragment = fragment;
String fragmentTag = fragment.getClass().getSimpleName();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
if (previousFragment != null) {
fragmentTransaction.remove(previousFragment);
}
fragmentTransaction.add(containerViewId, fragment, fragmentTag)
.commitNowAllowingStateLoss();
}
}
活动的布局:
<?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/root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="false"
android:background="@color/white"
android:stateListAnimator="@drawable/appbar_shadow"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/green"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:title=""
app:titleEnabled="false">
<include
layout="@layout/appbar_collapsing_part"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize"
app:layout_scrollFlags="scroll|exitUntilCollapsed" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/green"
android:stateListAnimator="@drawable/appbar_shadow"
app:layout_collapseMode="pin"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:theme="@style/ToolbarMenuItemsBackGroundTheme">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/title_txt"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/star_img"
android:ellipsize="end"
android:fontFamily="sans-serif-medium"
android:gravity="center_vertical"
android:maxLines="1"
android:textColor="@color/colorPrimaryDark"
android:textSize="19sp" />
<ImageView
android:id="@+id/star_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:layout_marginEnd="24dp"
android:padding="10dp"
android:src="@drawable/ic_favorite_filled" />
</RelativeLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
<android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:background="#45b0b2"
android:visibility="gone"
app:tabBackground="@drawable/backgr_blue_transparent_selector"
app:tabGravity="center"
app:tabIndicatorColor="@color/colorPrimaryDark"
app:tabIndicatorHeight="2dp"
app:tabMinWidth="500dp"
app:tabMode="fixed"
app:tabSelectedTextColor="@color/colorPrimaryDark"
app:tabTextAppearance="@style/CustomTabLayout"
app:tabTextColor="@color/green" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="@+id/fragment_content_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/blue"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<android.support.v4.view.ViewPager
android:id="@+id/view_pager_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
片段1:
public class MenuFragment1 extends Fragment {
public SomeCustomData transferedDataFromActivity;
private TextView data_1_txt;
public static MenuFragment1 newInstance(SomeCustomData data) {
Log.d("TEST", "MenuFragment1.newInstance");
MenuFragment1 fragment = new MenuFragment1();
Bundle args = new Bundle();
args.putSerializable("DATA_FROM_ACTIVITY", data);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("TEST", "MenuFragment1.onCreate");
if (getArguments() != null) {
this.transferedDataFromActivity = (SomeCustomData) getArguments().getSerializable("DATA_FROM_ACTIVITY");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d("TEST", "MenuFragment1.onCreateView");
View v = inflater.inflate(R.layout.menu_fragment_1, container, false);
data_1_txt = (TextView) v.findViewById(R.id.data_1_txt);
setupInOnCreateView();
return v;
}
protected void setupInOnCreateView() {
Log.d("TEST", "MenuFragment1.setupInOnCreateView");
//initialization of all view elements of layout with data is happens here.
setupData(transferedDataFromActivity);
}
public void setupData(SomeCustomData data) {
Log.d("TEST", "MenuFragment1.setupData");
this.transferedDataFromActivity = data;
if (transferedDataFromActivity != null) {
data_1_txt.setText(transferedDataFromActivity.Name);
}
}
}
片段1布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/green"
android:orientation="vertical">
<TextView
android:id="@+id/data_1_txt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/yellow"
android:text="Test"
android:textSize="20sp" />
<include layout="@layout/description_layout" />
</LinearLayout>
片段2:
public class MenuFragment2 extends Fragment {
public static MenuFragment2 newInstance() {
Log.d("TEST", "MenuFragment2.newInstance");
MenuFragment2 fragment = new MenuFragment2();
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d("TEST", "MenuFragment2.onCreateView");
View v = inflater.inflate(R.layout.menu_fragment_2, container, false);
setupInOnCreateView();
return v;
}
protected void setupInOnCreateView() {
Log.d("TEST", "MenuFragment2.setupInOnCreateView");
//initialization of all view elements of layout with data is happens here.
}
}
片段2布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/comments_scrollable_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible">
<LinearLayout
android:id="@+id/comments_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="@color/yellow" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="@color/blue" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="@color/yellow" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
TabMenuAdapter:
TabMenuAdapter:
public class TabMenuAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragments = new ArrayList<>();
private final List<String> mFragmentTitles = new ArrayList<>();
public TabMenuAdapter(FragmentManager fm) {
super(fm);
}
public void addFragment(Fragment fragment, String title) {
mFragments.add(fragment);
mFragmentTitles.add(title);
}
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return mFragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitles.get(position);
}
}
推荐答案
尝试一下
<android.support.design.widget.CoordinatorLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:title=""
app:titleEnabled="false">
<ImageView
android:layout_width="match_parent"
android:layout_height="256dp"
android:scaleType="fitXY"
android:src="@drawable/abc"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.CollapsingToolbarLayout>
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
app:layout_anchor="@id/appBar"
app:tabGravity="fill"
app:tabTextColor="#FFFFFF"
app:tabSelectedTextColor="#ff00"
app:tabMode="scrollable"
app:layout_anchorGravity="bottom" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
活动代码
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new BlankFragment(), "TAB-ONE");
adapter.addFragment(new BlankFragment(), "TAB-TWO");
adapter.addFragment(new BlankFragment(), "TAB-THREE");
viewPager.setAdapter(adapter);
}
}
片段代码
public class BlankFragment extends Fragment {
public BlankFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank, container, false);
}
}
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView 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"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".BlankFragment">
<ImageView
android:layout_width="match_parent"
android:layout_height="250dp"
android:layout_margin="5dp"
android:scaleType="centerCrop"
android:src="@drawable/kid_goku" />
<ImageView
android:layout_width="match_parent"
android:layout_height="250dp"
android:layout_margin="5dp"
android:scaleType="centerCrop"
android:src="@drawable/kid_goku" />
<ImageView
android:layout_width="match_parent"
android:layout_height="250dp"
android:layout_margin="5dp"
android:scaleType="centerCrop"
android:src="@drawable/kid_goku" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
public class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
您可以在此处 CollapsingToolbarLayout WITH TabLayout
观看视频>
You can see the video here CollapsingToolbarLayout WITH TabLayout
您可以从此处 CollapsingToolbarLayout WITH TabLayout
下载整个项目a>
You download the complete project from here CollapsingToolbarLayout WITH TabLayout
这篇关于折叠的AppBarLayout不与TabLayout和NestedScrollView一起滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!