Android滑动到顶部悬停

开发的过程中,会遇到一些不好解决的问题,列表太多会导致滑动事件的冲突,下图中的情况中就是一个很典型的案例。

UI

前言

要保证这个页面能正常显示,需要顶部的内容整体一起滑动上去,这样才能尽可能的扩大商品信息的展示面积,这也是有效信息。底部的双列表类似于饿了么的点餐界面。如果贸然使用ScrollView嵌套ListView的话,会导致ListView反复计算高度,导致内容错乱,进而影响页面效率的问题发生。因此需要寻找其他方式解决这个问题。

CoordinatorLayout

CoordinatorLayout是Google在com.android.support:design中封装的一个控件,其主要实现的效果需要配合ToolBar和AppBarLayout,由于ToolBar的可控性太低,因此在这里不使用ToolBar,使用LinearLayout放在屏幕顶部悬浮即可。

CoordinatorLayout

另外,由于底部显示的是结构有些复杂,因此将其他信息中的网页和店铺商品中的双列表分别放在两个Fragment中,用ViewPager统一显示。这样,可以尽可能避免事件冲突,并且还可以保持代码整洁。

编码

activity的布局文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<?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:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/main_green">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:text="供货商详情"
android:textColor="@color/white"
android:textSize="@dimen/textsize_9" />
</FrameLayout>
<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"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="@color/white"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<FrameLayout
android:id="@+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.8">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="123321\n123321\n123321\n123321\n123321\n123321\n123321\n123321\n123321\n" />
</FrameLayout>
</android.support.design.widget.CollapsingToolbarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<TextView
android:id="@+id/txtOtherInfo"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="其他信息" />
<TextView
android:id="@+id/txtShopGoods"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="店铺商品" />
</LinearLayout>
</android.support.design.widget.AppBarLayout>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/grey_line" />
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
</LinearLayout>

左侧fragment布局

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView 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"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.NestedScrollView>

原生的WebView 外面要加一层NestedScrollView,以便让外部的CoordinatorLayout获取滑动事件的监听,另外WebView的android:layout_height要设置为”match_parent”,否则网页中的返回顶部和到达底部等功能可能都无法使用了。

右侧fragment布局

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?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:orientation="horizontal">
<View
android:layout_width="100dp"
android:layout_height="match_parent"
android:background="@color/black_light" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

Activity代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public class CollapsingToolbarLayoutActivity extends AppCompatActivity {
private TextView txtOtherInfo, txtShopGoods;
private ViewPager viewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_collapsing);
super.onCreate(savedInstanceState);
txtOtherInfo = (TextView) findViewById(R.id.txtOtherInfo);
txtShopGoods = (TextView) findViewById(R.id.txtShopGoods);
txtOtherInfo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
viewPager.setCurrentItem(0);
}
});
txtShopGoods.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
viewPager.setCurrentItem(0);
}
});
viewPager = (ViewPager) findViewById(R.id.viewPager);
viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));
}
private static class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return WebViewFragment.getInstance();
default:
return ShopGoodsListFragment.getInstance();
}
}
@Override
public int getCount() {
return 2;
}
}
}

ShopGoodsListFragment代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public class ShopGoodsListFragment extends MyFragment {
public ShopGoodsListFragment() {
super();
}
public static ShopGoodsListFragment getInstance() {
return new ShopGoodsListFragment();
}
private MyActivity activity;
private RecyclerView recyclerView;
@Override
public void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.fragment_shop_goods);
super.onCreate(savedInstanceState);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(activity));
recyclerView.setAdapter(new MyRecyclerAdapter(activity));
}
private static class MyRecyclerAdapter extends RecyclerView.Adapter<MyRecyclerAdapter.ViewHolder> {
private Context context;
public MyRecyclerAdapter(Context context) {
this.context = context;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.recycleritem_goods, null, false);
return new ViewHolder(view);
}
@Override
public int getItemCount() {
return 50;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View itemView) {
super(itemView);
}
}
}
}

WebViewFragment代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class WebViewFragment extends MyFragment {
public WebViewFragment() {
super();
}
public static WebViewFragment getInstance() {
return new WebViewFragment();
}
@Override
public void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.fragment_viewpager);
super.onCreate(savedInstanceState);
HemaWebView webView = (HemaWebView) findViewById(R.id.webView);
webView.loadUrl("https://atwinner.github.io/2016/12/27/top-hover/");
}
}

效果

CoordinatorLayout

后记

由于时间仓促,没有将UI的内容100%的还原,但是代码中已经可以看到雏形,可以实现上下左右共存的滑动事件,并且展示复杂列表数据。可见com.android.support:design中给出的控件还是非常强大的,值得研究。

文章目录
  1. 1. 前言
  2. 2. CoordinatorLayout
  3. 3. 编码
    1. 3.1. activity的布局文件
    2. 3.2. 左侧fragment布局
    3. 3.3. 右侧fragment布局
    4. 3.4. Activity代码
    5. 3.5. ShopGoodsListFragment代码
    6. 3.6. WebViewFragment代码
  4. 4. 效果
  5. 5. 后记
|