问题
I am going to handle navigation drawer with sliding tabs using following Library called ObservableScrollView https://github.com/ksoichiro/Android-ObservableScrollView. The following are the xml and java files which I used to display.
My XML file:
<com.para.paraservice.observablescrollview.TouchInterceptionFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="@+id/pager_wrapper"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<RelativeLayout
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.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:popupTheme="@style/Theme.AppCompat.Light.DarkActionBar"
app:theme="@style/Toolbar" />
<com.para.paraservice.widgets.SlidingTabLayout
android:id="@+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="@dimen/tab_height"
android:background="@color/primary"
android:layout_below="@+id/toolbar" />
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/toolbar" >
<FrameLayout
android:id="@+id/fr_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true" />
<!-- android:layout_marginTop="?android:attr/actionBarSize" -->
<fragment
android:id="@+id/fragment_drawer"
android:name="com.para.paraservice.widgets.NavigationDrawerFragment"
android:layout_width="@dimen/flexible_space_image_height"
android:layout_height="match_parent"
android:layout_gravity="start"
app:layout="@layout/fragment_navigation_drawer" />
</android.support.v4.widget.DrawerLayout>
</RelativeLayout>
</com.para.paraservice.observablescrollview.TouchInterceptionFrameLayout>
My Java code:
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.widget.Toolbar;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.FrameLayout;
import android.widget.Toast;
import com.nineoldandroids.animation.ValueAnimator;
import com.nineoldandroids.view.ViewHelper;
import com.para.paraservice.BaseActivity;
import com.para.paraservice.R;
import com.para.paraservice.ViewPagerTab2ScrollViewFragment;
import com.para.paraservice.observablescrollview.ObservableScrollViewCallbacks;
import com.para.paraservice.observablescrollview.CacheFragmentStatePagerAdapter;
import com.para.paraservice.observablescrollview.ScrollState;
import com.para.paraservice.observablescrollview.ScrollUtils;
import com.para.paraservice.observablescrollview.Scrollable;
import com.para.paraservice.observablescrollview.TouchInterceptionFrameLayout;
import com.para.paraservice.widgets.NavigationDrawerCallbacks;
import com.para.paraservice.widgets.NavigationDrawerFragment;
import com.para.paraservice.widgets.SlidingTabLayout;
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("NewApi")
public class LandingActivity extends BaseActivity implements ObservableScrollViewCallbacks,
NavigationDrawerCallbacks {
private Toolbar mToolbar;
private View mToolbarView;
private TouchInterceptionFrameLayout mInterceptionLayout;
private ViewPager mPager;
private NavigationAdapter mPagerAdapter;
private int mSlop;
private boolean mScrolled;
private ScrollState mLastScrollState;
private NavigationDrawerFragment mNavigationDrawerFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.landing);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mToolbarView = findViewById(R.id.toolbar);
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
getSupportActionBar().setTitle("PARA");
getSupportActionBar().setDisplayShowHomeEnabled(true);
ViewCompat.setElevation(findViewById(R.id.header), getResources().getDimension(R.dimen.toolbar_elevation));
mPagerAdapter = new NavigationAdapter(getSupportFragmentManager());
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(mPagerAdapter);
final int tabHeight = getResources().getDimensionPixelSize(R.dimen.tab_height);
findViewById(R.id.pager_wrapper).setPadding(0, getActionBarSize() + tabHeight, 0, 0);
SlidingTabLayout slidingTabLayout = (SlidingTabLayout) findViewById(R.id.sliding_tabs);
slidingTabLayout.setCustomTabView(R.layout.tab_indicator, android.R.id.text1);
slidingTabLayout.setSelectedIndicatorColors(getResources().getColor(R.color.accent));
slidingTabLayout.setDistributeEvenly(true);
slidingTabLayout.setViewPager(mPager);
ViewConfiguration vc = ViewConfiguration.get(this);
mSlop = vc.getScaledTouchSlop();
mInterceptionLayout = (TouchInterceptionFrameLayout) findViewById(R.id.container);
mInterceptionLayout.setScrollInterceptionListener(mInterceptionListener);
mNavigationDrawerFragment = (NavigationDrawerFragment) getFragmentManager()
.findFragmentById(R.id.fragment_drawer);
mNavigationDrawerFragment.setup(R.id.fragment_drawer,
(DrawerLayout) findViewById(R.id.drawer), mToolbar);
}
@Override
public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
}
@Override
public void onDownMotionEvent() {
}
@Override
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
if (!mScrolled) {
// This event can be used only when TouchInterceptionFrameLayout
// doesn't handle the consecutive events.
adjustToolbar(scrollState);
}
}
private TouchInterceptionFrameLayout.TouchInterceptionListener mInterceptionListener = new TouchInterceptionFrameLayout.TouchInterceptionListener() {
@Override
public boolean shouldInterceptTouchEvent(MotionEvent ev, boolean moving, float diffX, float diffY) {
if (!mScrolled && mSlop < Math.abs(diffX) && Math.abs(diffY) < Math.abs(diffX)) {
// Horizontal scroll is maybe handled by ViewPager
return false;
}
Scrollable scrollable = getCurrentScrollable();
if (scrollable == null) {
mScrolled = false;
return false;
}
// If interceptionLayout can move, it should intercept.
// And once it begins to move, horizontal scroll shouldn't work any longer.
int toolbarHeight = mToolbarView.getHeight();
int translationY = (int) ViewHelper.getTranslationY(mInterceptionLayout);
boolean scrollingUp = 0 < diffY;
boolean scrollingDown = diffY < 0;
if (scrollingUp) {
if (translationY < 0) {
mScrolled = true;
mLastScrollState = ScrollState.UP;
return true;
}
} else if (scrollingDown) {
if (-toolbarHeight < translationY) {
mScrolled = true;
mLastScrollState = ScrollState.DOWN;
return true;
}
}
mScrolled = false;
return false;
}
@Override
public void onDownMotionEvent(MotionEvent ev) {
}
@Override
public void onMoveMotionEvent(MotionEvent ev, float diffX, float diffY) {
float translationY = ScrollUtils.getFloat(ViewHelper.getTranslationY(mInterceptionLayout) + diffY, -mToolbarView.getHeight(), 0);
ViewHelper.setTranslationY(mInterceptionLayout, translationY);
if (translationY < 0) {
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mInterceptionLayout.getLayoutParams();
lp.height = (int) (-translationY + getScreenHeight());
mInterceptionLayout.requestLayout();
}
}
@Override
public void onUpOrCancelMotionEvent(MotionEvent ev) {
mScrolled = false;
adjustToolbar(mLastScrollState);
}
};
private Scrollable getCurrentScrollable() {
Fragment fragment = getCurrentFragment();
if (fragment == null) {
return null;
}
View view = fragment.getView();
if (view == null) {
return null;
}
return (Scrollable) view.findViewById(R.id.scroll);
}
private void adjustToolbar(ScrollState scrollState) {
int toolbarHeight = mToolbarView.getHeight();
final Scrollable scrollable = getCurrentScrollable();
if (scrollable == null) {
return;
}
int scrollY = scrollable.getCurrentScrollY();
if (scrollState == ScrollState.DOWN) {
showToolbar();
} else if (scrollState == ScrollState.UP) {
if (toolbarHeight <= scrollY) {
hideToolbar();
} else {
showToolbar();
}
} else if (!toolbarIsShown() && !toolbarIsHidden()) {
// Toolbar is moving but doesn't know which to move:
// you can change this to hideToolbar()
showToolbar();
}
}
private Fragment getCurrentFragment() {
return mPagerAdapter.getItemAt(mPager.getCurrentItem());
}
private boolean toolbarIsShown() {
return ViewHelper.getTranslationY(mInterceptionLayout) == 0;
}
private boolean toolbarIsHidden() {
return ViewHelper.getTranslationY(mInterceptionLayout) == -mToolbarView.getHeight();
}
private void showToolbar() {
animateToolbar(0);
}
private void hideToolbar() {
animateToolbar(-mToolbarView.getHeight());
}
private void animateToolbar(final float toY) {
float layoutTranslationY = ViewHelper.getTranslationY(mInterceptionLayout);
if (layoutTranslationY != toY) {
ValueAnimator animator = ValueAnimator.ofFloat(ViewHelper.getTranslationY(mInterceptionLayout), toY).setDuration(200);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float translationY = (float) animation.getAnimatedValue();
ViewHelper.setTranslationY(mInterceptionLayout, translationY);
if (translationY < 0) {
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mInterceptionLayout.getLayoutParams();
lp.height = (int) (-translationY + getScreenHeight());
mInterceptionLayout.requestLayout();
}
}
});
animator.start();
}
}
@Override
public void onNavigationDrawerItemSelected(int position) {
Toast.makeText(this, "Menu item selected -> " + position,
Toast.LENGTH_SHORT).show();
}
@SuppressLint("NewApi")
@Override
public void onBackPressed() {
if (mNavigationDrawerFragment.isDrawerOpen())
mNavigationDrawerFragment.closeDrawer();
else
super.onBackPressed();
}
/**
* This adapter provides two types of fragments as an example.
* {@linkplain #createItem(int)} should be modified if you use this example for your app.
*/
private static class NavigationAdapter extends CacheFragmentStatePagerAdapter {
private static final String[] TITLES = new String[]{"Applepie", "Butter Cookie", "Cupcake", "Donut", "Eclair", "Froyo", "Gingerbread", "Honeycomb", "Ice Cream Sandwich", "Jelly Bean", "KitKat", "Lollipop"};
public NavigationAdapter(FragmentManager fm) {
super(fm);
}
@Override
protected Fragment createItem(int position) {
Fragment f;
final int pattern = position % 5;
switch (pattern) {
case 0:
f = new ViewPagerTab2ScrollViewFragment();
break;
case 1:
// f = new ViewPagerTab2ListViewFragment();
f = new ViewPagerTab2ScrollViewFragment();
break;
case 2:
// f = new ViewPagerTab2RecyclerViewFragment();
f = new ViewPagerTab2ScrollViewFragment();
break;
case 3:
// f = new ViewPagerTab2GridViewFragment();
f = new ViewPagerTab2ScrollViewFragment();
break;
case 4:
default:
f = new ViewPagerTab2ScrollViewFragment();
// f = new ViewPagerTab2WebViewFragment();
break;
}
return f;
}
@Override
public int getCount() {
return TITLES.length;
}
@Override
public CharSequence getPageTitle(int position) {
return TITLES[position];
}
}
}
So the sliding tab functionality working fine without Navigation Drawer.When i add navigation drawer layout to xml and java code to LandingActivity sliding tabs with view pager not working.Can you please tell me what exactly i am doing wrong here.Thanks in advance.
回答1:
Find ViewPagerTabListViewActivity.class and it layout layout/activity_viewpagertab.xml in ObservableScrollView samples
EDIT: Edited layout and class activity_viewpagertab.xml
<FrameLayout 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.v4.widget.DrawerLayout
android:id="@+id/drawer"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/toolbar_actionbar">
<!--<FrameLayout android:id="@+id/container" android:layout_width="match_parent"-->
<!--android:clickable="true" android:layout_height="match_parent" />-->
<!--
Padding for ViewPager must be set outside the ViewPager itself
because with padding, EdgeEffect of ViewPager become strange.
-->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:paddingTop="@dimen/tab_height"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:popupTheme="@style/Theme.AppCompat.Light.DarkActionBar"
app:theme="@style/Toolbar" />
<com.google.samples.apps.iosched.ui.widget.SlidingTabLayout
android:id="@+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="@dimen/tab_height"
android:background="@color/primary" />
</LinearLayout>
</FrameLayout>
<!-- android:layout_marginTop="?android:attr/actionBarSize"-->
<fragment
android:id="@+id/fragment_drawer"
android:name="com.github.ksoichiro.android.observablescrollview.samples.NavigationDrawerFragment"
android:layout_width="280dp"
android:layout_height="match_parent"
android:layout_gravity="start"
app:layout="@layout/fragment_navigation_drawer" />
</android.support.v4.widget.DrawerLayout>
</FrameLayout>
part of ViewPagerTabListViewActivity.class
public class ViewPagerTabListViewActivity extends BaseActivity implements ObservableScrollViewCallbacks, NavigationDrawerCallbacks {
private View mHeaderView;
private View mToolbarView;
private int mBaseTranslationY;
private ViewPager mPager;
private NavigationAdapter mPagerAdapter;
private NavigationDrawerFragment mNavigationDrawerFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_viewpagertab);
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
mHeaderView = findViewById(R.id.header);
ViewCompat.setElevation(mHeaderView, getResources().getDimension(R.dimen.toolbar_elevation));
mToolbarView = findViewById(R.id.toolbar);
mPagerAdapter = new NavigationAdapter(getSupportFragmentManager());
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(mPagerAdapter);
SlidingTabLayout slidingTabLayout = (SlidingTabLayout) findViewById(R.id.sliding_tabs);
slidingTabLayout.setCustomTabView(R.layout.tab_indicator, android.R.id.text1);
slidingTabLayout.setSelectedIndicatorColors(getResources().getColor(R.color.accent));
slidingTabLayout.setDistributeEvenly(true);
slidingTabLayout.setViewPager(mPager);
// When the page is selected, other fragments' scrollY should be adjusted
// according to the toolbar status(shown/hidden)
slidingTabLayout.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i2) {
}
@Override
public void onPageSelected(int i) {
propagateToolbarState(toolbarIsShown());
}
@Override
public void onPageScrollStateChanged(int i) {
}
});
propagateToolbarState(toolbarIsShown());
//Added this --------------------------------------------
ActionBar ab = getSupportActionBar();
ab.setDisplayShowHomeEnabled(false);
ab.setDisplayHomeAsUpEnabled(true);
ab.setHomeButtonEnabled(true);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.fragment_drawer);
// Set up the drawer.
mNavigationDrawerFragment.setup(R.id.fragment_drawer, (DrawerLayout) findViewById(R.id.drawer), (Toolbar) mToolbarView);
}
//Added this -----------------------------------------
@Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
Toast.makeText(this, "Menu item selected -> " + position, Toast.LENGTH_SHORT).show();
}
Now it works like a charm, shared a screenshot. Glad to work on your problem thanks.
来源:https://stackoverflow.com/questions/29532083/slidingtablayout-with-navigationdrawer