下面是下拉刷新上拉加载可以左右滑动的实例,下面是效果图:
GitHub 下载地址:https://github.com/wuqingsen/MySlidingNested
CSDN 下载地址:https://download.csdn.net/download/wuqingsen1/11072595
下面就来看下如何实现的;
首先看 xml 文件中的代码:
<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:background="@color/white">
<com.andview.refreshview.XRefreshView
android:id="@+id/xRefreshView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.qd.myslidingnested.utils.MyCoordinatorLayout
android:id="@+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:descendantFocusability="blocksDescendants">
<TextView
android:id="@+id/tvTitle"
android:layout_width="match_parent"
android:layout_height="50dp"
android:ellipsize="end"
android:gravity="center"
android:text="标题"
android:textColor="#FF171717"
android:textSize="14sp" />
<ImageView
android:id="@+id/iv_one"
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_below="@+id/tvTitle"
android:scaleType="fitXY"
android:src="@drawable/icon_one" />
</RelativeLayout>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<com.example.qd.myslidingnested.utils.MyNestedScrollView
android:id="@+id/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="@string/mybehavior">
<com.example.qd.myslidingnested.utils.VerticalLinearLayout
android:id="@+id/NestedVerLinearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical">
<com.ogaclejapan.smarttablayout.SmartTabLayout
android:id="@+id/smartTabLayout"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/white"
android:overScrollMode="never"
app:stl_defaultTabTextHorizontalPadding="24dp"
app:stl_dividerColor="@android:color/transparent"
app:stl_indicatorThickness="0dp"
app:stl_underlineThickness="0dp"
app:tabBackground="@color/white"
app:tabIndicatorHeight="0dp"
app:tabMode="scrollable" />
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.example.qd.myslidingnested.utils.VerticalLinearLayout>
</com.example.qd.myslidingnested.utils.MyNestedScrollView>
</com.example.qd.myslidingnested.utils.MyCoordinatorLayout>
</com.andview.refreshview.XRefreshView>
</RelativeLayout>
最外层是 XRefreshView ,这是一个下拉刷新的框架,重写了里面的代码,解决下拉的冲突;
其次是就是经典的 CoordinatorLayout 嵌套 AppBarLayout 和 NestedScrollView 实现滑动置顶和 ViewPager 左右滑动的功能;其中 MyCoordinatorLayout 继承 CoordinatorLayout 解决滑动冲突。
MyCoordinatorLayout 和 MyNestedScrollView 可以下载源码查看。
接下来是 MainActivity 的代码:
public class MainActivity extends AppCompatActivity implements AppBarLayoutObserved {
@BindView(R.id.coordinatorLayout)
MyCoordinatorLayout coordinatorLayout;
@BindView(R.id.appbarLayout)
AppBarLayout appbarLayout;
@BindView(R.id.nestedScrollView)
MyNestedScrollView nestedScrollView;
@BindView(R.id.smartTabLayout)
SmartTabLayout smartTabLayout;
@BindView(R.id.viewPager)
ViewPager mViewPager;
@BindView(R.id.xRefreshView)
XRefreshView xRefreshView;
private FragmentAdapter fragmentAdapter;
private List<MyFragment> fragments;
private List<String> mDataList;
private HashMap<Integer, SuperTextView> mapTitle;
private int mStatus = STATUS_EXPANDED;
public static final int STATUS_EXPANDED = 1;//展开
public static final int STATUS_COLLAPSED = 2;//收缩
private int headHeight;
private int minHeadTopHeight;
private int lastVerticalOffset = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
setList();
setView();
setListener();
}
private void setList() {
fragments = new ArrayList<>();
mapTitle = new HashMap<>();
mDataList = new ArrayList<>();
mDataList.add("热门");
mDataList.add("关注");
mDataList.add("游戏");
mDataList.add("音乐");
mDataList.add("直播");
mDataList.add("娱乐");
mDataList.add("性教育");
mDataList.add("PM2.5");
for (int i = 0; i < mDataList.size(); i++) {
fragments.add(new MyFragment());
}
}
private void setView() {
fragmentAdapter = new FragmentAdapter(getSupportFragmentManager(), fragments);
mViewPager.setAdapter(fragmentAdapter);
coordinatorLayout.setCurrentScrollableContainer(fragments.get(0));
smartTabLayout.setCustomTabView(new MyTabProvider());
smartTabLayout.setViewPager(mViewPager);
headHeight = (int) this.getResources().getDimension(R.dimen.headHeight);
minHeadTopHeight = (int) this.getResources().getDimension(R.dimen.minHeadTopHeight);
}
private void setListener() {
xRefreshView.setPullRefreshEnable(true);
xRefreshView.setPullLoadEnable(false);
//防止横向滑动冲突
xRefreshView.setMoveForHorizontal(true);
//下拉刷新
xRefreshView.setXRefreshViewListener(new XRefreshView.SimpleXRefreshListener() {
@Override
public void onRefresh(boolean isPullDown) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
xRefreshView.stopRefresh(true);
}
}, 1500);
}
});
//标题滑动监听
appbarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
//verticalOffset 向上滑动得到的值是负的,初始值为0 就是展开状态
//剩下未滑出屏幕的高度
int h = headHeight + verticalOffset;
if (verticalOffset == 0) {
//展开状态
mStatus = STATUS_EXPANDED;
} else if (h == minHeadTopHeight) {
mStatus = STATUS_COLLAPSED;
} else {
mStatus = 0;
}
if (lastVerticalOffset != verticalOffset) {
lastVerticalOffset = verticalOffset;
}
}
});
//viewPager滑动监听
mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
coordinatorLayout.setCurrentScrollableContainer(fragments.get(position));
for (HashMap.Entry<Integer, SuperTextView> entry : mapTitle.entrySet()) {
setTitle(false, entry.getValue());
}
setTitle(true, mapTitle.get(position));
}
});
coordinatorLayout.setAppBarLayoutObserved(this);
coordinatorLayout.setxRefreshView(xRefreshView);
coordinatorLayout.setNestedScrollView(nestedScrollView);
}
@Override
public int getAppBarLayoutStatus() {
return mStatus;
}
/**
* MyTitle
*/
private class MyTabProvider implements SmartTabLayout.TabProvider {
private LayoutInflater inflater;
public MyTabProvider() {
inflater = LayoutInflater.from(MainActivity.this);
}
@Override
public View createTabView(ViewGroup container, int position, PagerAdapter adapter) {
View view = inflater.inflate(R.layout.my_tab_layout, container, false);
SuperTextView superTextView = view.findViewById(R.id.tab_text);
mapTitle.put(position, superTextView);
superTextView.setText(mDataList.get(position));
setTitle(false, superTextView);
//选中第一项
if (position == 0) {
setTitle(true, superTextView);
}
return view;
}
}
/**
* setTitleStyle
* @param isShowState true:显示对号;否则隐藏
*/
private void setTitle(boolean isShowState, SuperTextView superTextView) {
if (isShowState) {
//字体大小为20,并且加粗
superTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
superTextView.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
superTextView.setTextColor(Color.parseColor("#FF333333"));
superTextView.setShowState(true);
} else {
superTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
superTextView.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
superTextView.setTextColor(Color.parseColor("#FF999999"));
superTextView.setShowState(false);
}
}
}
在这里面设置标题和 ViewPager 的样式和内容以及监听 appbarLayout 的状态。
代码量较多,请下载源码观看,注释很清楚,就不多写了。