相信大家在日常开发过程中有遇到过类似的需求,ViewPager+Header ,ViewPager里面有ListView或者ScrollerView,这个界面如果我们自己来实现的话,需要处理各种手势冲突,还是挺麻烦的,之前看过鸿洋大大写过一篇解决这个问题的博文,Android 自定义控件 轻松实现360软件详情页 ,本篇文章说的是如何通过系统控件实现这个效果。
360软件详情页
这里使用的系统控件是CoordinatorLayout、AppBarLayout、ViewPager、PagerTabStrip。
MainActivity
package com.sundroid.coordinator.view;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private ViewPager view_pager;
private List<String> titles = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
view_pager = (ViewPager) findViewById(R.id.view_pager);
titles.add("简介");
titles.add("评价");
titles.add("相关");
List<Fragment> fragments = new ArrayList<>();
fragments.add(ListFragment.newInstance());
fragments.add(ListFragment.newInstance());
fragments.add(ListFragment.newInstance());
ViewPagerAdapter mAdapter = new ViewPagerAdapter(getSupportFragmentManager(), fragments);
view_pager.setAdapter(mAdapter);
}
private class ViewPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments = new ArrayList<>();
public ViewPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
return titles.get(position);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
}
ListFragment
package com.sundroid.coordinator.view;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by sundroid on 16/05/2017.
*/
public class ListFragment extends Fragment {
private View mRootView;
private ListView listview;
private String[] name = {"Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World",
"Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World",
"Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World",
"Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World",
"Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World", "Hello World"};
static ListFragment newInstance() {
ListFragment f = new ListFragment();
return f;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if (mRootView == null) {
mRootView = inflater.inflate(R.layout.view_page_item_1, null);
}
listview = (ListView) mRootView.findViewById(R.id.listview);
listview.setNestedScrollingEnabled(true);
List<Map<String, Object>> listems = new ArrayList<Map<String, Object>>();
for (int i = 0; i < name.length; i++) {
Map<String, Object> listem = new HashMap<String, Object>();
listem.put("name", name[i]);
listems.add(listem);
}
SimpleAdapter simplead = new SimpleAdapter(getActivity(), listems,
R.layout.list_item, new String[]{"name"},
new int[]{R.id.name});
listview.setAdapter(simplead);
//缓存的rootView需要判断是否已经被加过parent, 如果有parent需要从parent删除,要不然会发生这个rootview已经有parent的错误。
ViewGroup parent = (ViewGroup) mRootView.getParent();
if (parent != null) {
parent.removeView(mRootView);
}
return mRootView;
}
}
activity_main.xml
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:focusableInTouchMode="true"
android:splitMotionEvents="false">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="300dp"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="软件介绍"
android:textColor="#ffffff" />
</RelativeLayout>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never">
<android.support.v4.view.PagerTabStrip
android:layout_width="match_parent"
android:layout_height="48dp" />
</android.support.v4.view.ViewPager>
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
需要注意的是滑动的View需要设置listview.setNestedScrollingEnabled(true),否则滑动会失效。这里只介绍用法,不涉及原理,有任何疑问的同学可以留言,接下来会写一篇关于CoordinatorLayout实现原理的文章,敬请关注。