Android自定义横向滑动菜单的实现

时间:2022-09-20 14:33:48

本文讲述了Android自定义横向滑动菜单的实现。分享给大家供大家参考,具体如下:

前言

 开发安卓过程中,经常会用到标题栏的样式,有时候传统方式不能满足开发者的需要,这时候就需要自定义控件来实现。(注意:本文提供思路,有关键代码,但是代码不全)

标题栏说明

自定义标题栏ColumnHorizontalScrollView继承HorizontalScrollView 这个安卓原生的控件,HorizontalScrollView是一种FrameLayout(框架布局),其子项被滚动查看时是整体移动的,并且子项本身可以是一个有复杂层次结构的布局管理器。一个常见的应用是子项在水平方向中,用户可以滚动显示顶层水平排列的子项(items)。

在布局文件中添加ColumnHorizontalScrollView控件

?
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
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tabs="http://schemas.android.com/apk/res-auto"
 android:id="@+id/homeTabs"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:background="@color/db_bg_gray"
 android:orientation="vertical">
 <com.wankr.app.widget.ColumnHorizontalScrollView
     android:id="@+id/mColumnHorizontalScrollView"
  android:layout_height="match_parent"
  android:layout_width="wrap_content"
  android:layout_centerVertical="true"
  android:scrollbars="none">
  <LinearLayout
   android:id="@+id/mRadioGroup_content"
   android:layout_width="fill_parent"
   android:layout_height="match_parent"
   android:layout_centerVertical="true"
   android:gravity="center_vertical"
   android:orientation="horizontal"
   android:paddingLeft="10.0dip"
   android:paddingRight="10.0dip" />
 </com.wankr.app.widget.ColumnHorizontalScrollView>
 <android.support.v4.view.ViewPager
   android:id="@+id/contentPager"
   android:layout_width="match_parent"
   android:layout_height="0dp"
   android:layout_weight="1" />
</LinearLayout>

横向菜单中展示界面
注意:可以设置菜单中标题的宽度大小,最好标题宽度一致。

?
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
package com.example.app;
import java.util.ArrayList;
import java.util.List;
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.v4.view.ViewPager.LayoutParams;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends Fragment implements OnClickListener {
 private ViewPager contentPager;
 private ContentPagerAdapter pagerAdapter;
 private ColumnHorizontalScrollView mColumnHorizontalScrollView;
 private LinearLayout mRadioGroup_content;
 /** 请求CODE */
 public final static int CHANNELREQUEST = 1;
 /** 屏幕宽度 */
 private int mScreenWidth = 0;
 /** Item宽度 */
 private int mItemWidth = 0;
 /** 当前选中的栏目*/
 private int columnSelectIndex = 0;
 // 标签信息
 private List<ChannelItem> channelItems = new ArrayList<ChannelItem>();
 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
   Bundle savedInstanceState) {
  View v = inflater.inflate(R.layout.activity_main, container , false);
  this.contentPager = (ViewPager) v.findViewById(R.id.contentPager);
  this.pagerAdapter = new ContentPagerAdapter(getChildFragmentManager());
  this.contentPager.setAdapter(this.pagerAdapter);
  this.contentPager.setCurrentItem(0);
  this.contentPager.setOnPageChangeListener(pageListener);
  this.mColumnHorizontalScrollView = (ColumnHorizontalScrollView) v.findViewById(R.id.mColumnHorizontalScrollView);
  this.mRadioGroup_content = (LinearLayout) v.findViewById(R.id.mRadioGroup_content);
  this.setChangeView();
  return v;
 }
 /**
  * 设置标题适配器
  * @author raotaisen
  *
  */
 private class ContentPagerAdapter extends FragmentPagerAdapter {
  public ContentPagerAdapter(FragmentManager fm) {
   super(fm);
   // TODO Auto-generated constructor stub
  }
  @Override
  public Fragment getItem(int arg0) {
   // TODO Auto-generated method stub
   return null;
  }
  @Override
  public int getCount() {
   // TODO Auto-generated method stub
   return channelItems.size();
  }
  /**
   * 标题设置
   */
  @Override
  public CharSequence getPageTitle(int position) {
   ChannelItem item = channelItems.get(position);
   return item.getChanneName();
  }
 }
 /**
  * ViewPager切换监听方法
  * */
 public ViewPager.OnPageChangeListener pageListener= new ViewPager.OnPageChangeListener(){
  @Override
  public void onPageScrollStateChanged(int arg0) {
  }
  @Override
  public void onPageScrolled(int arg0, float arg1, int arg2) {
  }
  @Override
  public void onPageSelected(int position) {
   contentPager.setCurrentItem(position);
   selectTab(position);
  }
 };
 /**
  * 选择的Column里面的Tab
  * */
 private void selectTab(int tab_postion) {
  columnSelectIndex = tab_postion;
  for (int i = 0; i < mRadioGroup_content.getChildCount(); i++) {
   View checkView = mRadioGroup_content.getChildAt(tab_postion);
   int k = checkView.getMeasuredWidth();
   int l = checkView.getLeft();
   int i2 = l + k / 2 - mScreenWidth / 2;
   // rg_nav_content.getParent()).smoothScrollTo(i2, 0);
   mColumnHorizontalScrollView.smoothScrollTo(i2, 0);
   // mColumnHorizontalScrollView.smoothScrollTo((position - 2) *
   // mItemWidth , 0);
  }
  //判断是否选中
  for (int j = 0; j < mRadioGroup_content.getChildCount(); j++) {
   View checkView = mRadioGroup_content.getChildAt(j);
   boolean ischeck;
   if (j == tab_postion) {
    ischeck = true;
   } else {
    ischeck = false;
   }
   checkView.setSelected(ischeck);
  }
  // 指向对应的tab位置
  switch (tab_postion) {
  }
 }
 /**
  * 当栏目项发生变化时候调用
  */
 private void setChangeView() {
  gettColumnData();
  initTabColumn();
 }
 /**
  * 获取标签栏数据
  */
 private void gettColumnData() {
  channelItems.clear();
  channelItems.add(new ChannelItem(null, "葱葱"));
  channelItems.add(new ChannelItem(null, "飞飞"));
  channelItems.add(new ChannelItem(null, "vv"));
  channelItems.add(new ChannelItem(null, "刚子"));
  channelItems.add(new ChannelItem(null, "最新"));
  /**
   * 标题可以动态设置长度。获取数据添加到集合中展示。
   */
  pagerAdapter.notifyDataSetChanged();
 }
 /**
  *初始化Column栏目项
  */
 private void initTabColumn() {
  mRadioGroup_content.removeAllViews();
  int count = channelItems.size();
  // 设置横向菜单栏中item属性
  mColumnHorizontalScrollView.setParam(getActivity(), mScreenWidth, mRadioGroup_content, null, null, null, null);
  for(int i = 0; i< count; i++){
   LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT , LayoutParams.WRAP_CONTENT);
   params.leftMargin = 6;
   params.rightMargin = 6;
//   TextView localTextView = (TextView) mInflater.inflate(R.layout.column_radio_item, null);
   TextView columnTextView = new TextView(getActivity());
   columnTextView.setTextSize(16);
   columnTextView.setGravity(Gravity.CENTER);
   columnTextView.setPadding(5, 5, 5, 5);
   columnTextView.setId(i);
   columnTextView.setText(channelItems.get(i).getChanneName());
//   columnTextView.setTextColor(getResources().getColorStateList(R.color.top_category_scroll_text_color_day));
   if(columnSelectIndex == i){
    columnTextView.setSelected(true);
   }
   // 对item的监听
   columnTextView.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
     for(int i = 0;i < mRadioGroup_content.getChildCount();i++){
      View localView = mRadioGroup_content.getChildAt(i);
      if (localView != v) {
       localView.setSelected(false);
      }else{
       localView.setSelected(true);
       contentPager.setCurrentItem(i);
      }
     }
//     Toast.makeText(getApplicationContext(), userChannelList.get(v.getId()).getName(), Toast.LENGTH_SHORT).show();
    }
   });
   mRadioGroup_content.addView(columnTextView, i ,params);
  }
 }
 @Override
 public void onClick(View v) {
  // TODO Auto-generated method stub
 }
 
}

标题菜单横向滑动自定义控件

?
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
94
95
96
97
98
99
100
101
102
103
104
package com.example.app;
import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
public class ColumnHorizontalScrollView extends HorizontalScrollView {
 /** 传入整体布局 */
 private View ll_content;
 /** 传入更多栏目选择布局 */
 private View ll_more;
 /** 传入拖动栏布局 */
 private View rl_column;
 /** 左阴影图片 */
 private ImageView leftImage;
 /** 右阴影图片 */
 private ImageView rightImage;
 /** 屏幕宽度 */
 private int mScreenWitdh = 0;
 /** 父类的活动activity */
 private Activity activity;
 public ColumnHorizontalScrollView(Context context) {
  super(context);
 }
 public ColumnHorizontalScrollView(Context context, AttributeSet attrs) {
  super(context, attrs);
 }
 public ColumnHorizontalScrollView(Context context, AttributeSet attrs,
          int defStyle) {
  super(context, attrs, defStyle);
 }
 /**
  * 在拖动的时候执行
  * */
 @Override
 protected void onScrollChanged(int paramInt1, int paramInt2, int paramInt3, int paramInt4) {
  // TODO Auto-generated method stub
  super.onScrollChanged(paramInt1, paramInt2, paramInt3, paramInt4);
  shade_ShowOrHide();
  if(!activity.isFinishing() && ll_content !=null && leftImage!=null && rightImage!=null && ll_more!=null && rl_column !=null){
   if(ll_content.getWidth() <= mScreenWitdh){
    leftImage.setVisibility(View.GONE);
    rightImage.setVisibility(View.GONE);
   }
  }else{
   return;
  }
  if(paramInt1 ==0){
   leftImage.setVisibility(View.GONE);
   rightImage.setVisibility(View.VISIBLE);
   return;
  }
  if(ll_content.getWidth() - paramInt1 + ll_more.getWidth() + rl_column.getLeft() == mScreenWitdh){
   leftImage.setVisibility(View.VISIBLE);
   rightImage.setVisibility(View.GONE);
   return;
  }
  leftImage.setVisibility(View.VISIBLE);
  rightImage.setVisibility(View.VISIBLE);
 }
 /**
  * 传入父类布局中的资源文件
  * */
 public void setParam(Activity activity, int mScreenWitdh,View paramView1,ImageView paramView2, ImageView paramView3 ,View paramView4,View paramView5){
  this.activity = activity;
  this.mScreenWitdh = mScreenWitdh;
  ll_content = paramView1;
  leftImage = paramView2;
  rightImage = paramView3;
  ll_more = paramView4;
  rl_column = paramView5;
 }
 /**
  * 判断左右阴影的显示隐藏效果
  * */
 public void shade_ShowOrHide() {
  if (!activity.isFinishing() && ll_content != null) {
   measure(0, 0);
   //如果整体宽度小于屏幕宽度的话,那左右阴影都隐藏
   if (mScreenWitdh >= getMeasuredWidth()) {
    leftImage.setVisibility(View.GONE);
    rightImage.setVisibility(View.GONE);
   }
  } else {
   return;
  }
  //如果滑动在最左边时候,左边阴影隐藏,右边显示
  if (getLeft() == 0) {
   leftImage.setVisibility(View.GONE);
   rightImage.setVisibility(View.VISIBLE);
   return;
  }
  //如果滑动在最右边时候,左边阴影显示,右边隐藏
  if (getRight() == getMeasuredWidth() - mScreenWitdh) {
   leftImage.setVisibility(View.VISIBLE);
   rightImage.setVisibility(View.GONE);
   return;
  }
  //否则,说明在中间位置,左、右阴影都显示
  leftImage.setVisibility(View.VISIBLE);
  rightImage.setVisibility(View.VISIBLE);
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/aa6227716/article/details/45893747