Android 自定义横向滚动条
来源:互联网 发布:ca检测不到网络 编辑:程序博客网 时间:2024/05/20 06:30
Android 自定义横向滚动条。当你的横向字段或者表格很多时候,显示不下内容,可以使用很想滚动条进行滚动。竖向方面我添加了listview进行添加数据。两者滚动互不干扰。横向滚动条的可以自定义不同的字段的,进行加载就行了。接下来看看效果图,再看代码。
一、效果图
二、自定义MyHScrollView继承HorizontalScrollView
package com.org.scrollview;import java.util.ArrayList;import java.util.List;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.widget.HorizontalScrollView;/* * 自定义的 滚动控件 * 重载了 onScrollChanged(滚动条变化),监听每次的变化通知给 观察(此变化的)观察者 * 可使用 AddOnScrollChangedListener 来订阅本控件的 滚动条变化 * */public class MyHScrollView extends HorizontalScrollView {ScrollViewObserver mScrollViewObserver = new ScrollViewObserver();public MyHScrollView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);// TODO Auto-generated constructor stub}public MyHScrollView(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stub}public MyHScrollView(Context context) {super(context);// TODO Auto-generated constructor stub}@Overridepublic boolean onTouchEvent(MotionEvent ev) {Log.i("pdwy","MyHScrollView onTouchEvent");return super.onTouchEvent(ev);}@Overrideprotected void onScrollChanged(int l, int t, int oldl, int oldt) {/* * 当滚动条移动后,引发 滚动事件。通知给观察者,观察者会传达给其他的。 */if (mScrollViewObserver != null /*&& (l != oldl || t != oldt)*/) {mScrollViewObserver.NotifyOnScrollChanged(l, t, oldl, oldt);}super.onScrollChanged(l, t, oldl, oldt);}/* * 订阅 本控件 的 滚动条变化事件 * */public void AddOnScrollChangedListener(OnScrollChangedListener listener) {mScrollViewObserver.AddOnScrollChangedListener(listener);}/* * 取消 订阅 本控件 的 滚动条变化事件 * */public void RemoveOnScrollChangedListener(OnScrollChangedListener listener) {mScrollViewObserver.RemoveOnScrollChangedListener(listener);}/* * 当发生了滚动事件时 */public static interface OnScrollChangedListener {public void onScrollChanged(int l, int t, int oldl, int oldt);}/* * 观察者 */public static class ScrollViewObserver {List<OnScrollChangedListener> mList;public ScrollViewObserver() {super();mList = new ArrayList<OnScrollChangedListener>();}public void AddOnScrollChangedListener(OnScrollChangedListener listener) {mList.add(listener);}public void RemoveOnScrollChangedListener(OnScrollChangedListener listener) {mList.remove(listener);}public void NotifyOnScrollChanged(int l, int t, int oldl, int oldt) {if (mList == null || mList.size() == 0) {return;}for (int i = 0; i < mList.size(); i++) {if (mList.get(i) != null) {mList.get(i).onScrollChanged(l, t, oldl, oldt);}}}}}
三、InterceptScrollContainer这个类把表头的滚动下发到每一个listview的item中。
package com.org.scrollview;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.widget.LinearLayout;/* * * 一个视图容器控件 * 阻止 拦截 ontouch事件传递给其子控件 * */public class InterceptScrollContainer extends LinearLayout {public InterceptScrollContainer(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stub}public InterceptScrollContainer(Context context) {super(context);// TODO Auto-generated constructor stub}////@Override//public boolean dispatchTouchEvent(MotionEvent ev) {//// TODO Auto-generated method stub////return super.dispatchTouchEvent(ev);//Log.i("pdwy","ScrollContainer dispatchTouchEvent");//return true;//}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {// TODO Auto-generated method stub//return super.onInterceptTouchEvent(ev);Log.i("pdwy","ScrollContainer onInterceptTouchEvent");return true;//return super.onInterceptTouchEvent(ev);}//@Override//public boolean onTouchEvent(MotionEvent event) {//// TODO Auto-generated method stub//Log.i("pdwy","ScrollContainer onTouchEvent");//return true;//}}
三、自定义统一管理类CustomListScrollManageActivity
package com.org.horizontalscrollview;import java.util.ArrayList;import java.util.LinkedList;import com.org.scrollview.MyHScrollView;import com.org.scrollview.MyHScrollView.OnScrollChangedListener;import android.app.Activity;import android.content.Context;import android.os.Bundle;import android.util.DisplayMetrics;import android.util.Log;import android.view.Gravity;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.widget.AdapterView;import android.widget.BaseAdapter;import android.widget.CheckBox;import android.widget.CompoundButton;import android.widget.LinearLayout;import android.widget.ListView;import android.widget.TextView;import android.widget.CompoundButton.OnCheckedChangeListener;import android.widget.Toast;public abstract class CustomListScrollManageActivity extends Activity{//列表的标题protected ArrayList<String> mListHeadItemsName = new ArrayList<String>();//每一项checkbox的记录列表protected LinkedList<ItemStatus> mItemsExtendData;//列表整体标题栏private LinearLayout mListHead = null;//列表整体标题栏滚动条private MyHScrollView mHScrollView = null;//是否显示第一列protected boolean mIsShowTextIndex = true;//listview的适配器protected ListNumScrollAdapter mAdapter;//整体的根布局protected int mRootLayout = R.layout.layout_common_sroll;//设置是否支持长按protected boolean mItemCanLongClick = true;//处于长按状态true,不是长按状态falseprotected boolean mLongClickStatus = false;//checkbox的状态protected class ItemStatus {public boolean mIsCheckBoxVisible = false;public boolean mIsCheckBoxSelected = false;}//实例化每一项checkbox的记录列表mItemsExtendDataprotected LinkedList<ItemStatus> GetItemsExtendData() {if (mItemsExtendData == null) mItemsExtendData = new LinkedList<ItemStatus>();return mItemsExtendData;}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(mRootLayout);}//子类继承后初始化子类数据后,需要调用这个,初始化父类。protected void initView() {mListHead = (LinearLayout) findViewById(R.id.surfaceManagerListHead);mHScrollView = (MyHScrollView) mListHead.findViewById(R.id.MyHScrollView_head);ListView listItem = (ListView)findViewById(R.id.listViewCommonFeatureItems);//设置表头的触摸滑动事件mHScrollView.setOnTouchListener(new ListViewAndHeadViewTouchLinstener());listItem.setOnItemClickListener(new OnItemClickListener());listItem.setOnItemLongClickListener(new OnItemLongClickListener());mAdapter = new ListNumScrollAdapter(this);listItem.setAdapter(mAdapter);mListHeadItemsName = getReadListHeadItems();recreateHeadControl();initCheckBoxVilible();setCheckBoxStatue(false);mAdapter.notifyDataSetChanged();}//加载表头列表数据protected void recreateHeadControl() {mListHead.setFocusable(true);mListHead.setClickable(true);mListHead.setOnTouchListener(new ListViewAndHeadViewTouchLinstener());TextView headIndex = (TextView)mListHead.findViewById(R.id.textIndex);setTextParams(headIndex, mListHeadItemsName.size());headIndex.setText("序号");headIndex.setVisibility(mIsShowTextIndex == true?View.VISIBLE:View.GONE);LinearLayout layout_items = (LinearLayout)mListHead.findViewById(R.id.layoutTextHeadItems);layout_items.removeAllViews();for (int i = 0; i < mListHeadItemsName.size(); i++) {TextView text=new TextView(this);text.setTextColor(getResources().getColor(R.color.list_head));setTextParams(text, mListHeadItemsName.size());text.setText(mListHeadItemsName.get(i));layout_items.addView(text);}}//初始化每一项的CheckBoxprivate void initCheckBoxVilible(){GetItemsExtendData().clear();for (int i = 0; i < getItemsCount(); i++) {ItemStatus itemData = new ItemStatus();// 插入队列GetItemsExtendData().add(itemData);}}class ListViewAndHeadViewTouchLinstener implements View.OnTouchListener {@Overridepublic boolean onTouch(View arg0, MotionEvent event) {//当在列头 和 listView控件上touch时,将这个touch的事件分发给 ScrollViewtry {mHScrollView.onTouchEvent(event);} catch (IllegalArgumentException e) { e.printStackTrace(); return false; }return false; }}//抽象接口,列表标题栏public abstract ArrayList<String> getReadListHeadItems();//抽象接口,listview整体数据项public abstract int getItemsCount();/** * 抽象接口,listview每一项数据的装载,装载返回是 * @param recordIndex * @return ArrayList<String> */public abstract ArrayList<String> getIndexDataArray(int recordIndex);//////////////////////////////////////////////////////////////需要每一项编辑或者增加,删除数据的抽象接口,请看具体情况自行添加/** * listview适配器 * @author Administrator * */public class ListNumScrollAdapter extends BaseAdapter implements OnCheckedChangeListener {private Context mContext;private LayoutInflater mLayoutInflater;public ListNumScrollAdapter(Context context) {this.mContext = context;mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);}@Overridepublic int getCount() {Log.e("Show", String.valueOf(getItemsCount()));return getItemsCount();}@Overridepublic Object getItem(int arg0) {return null;}@Overridepublic long getItemId(int arg0) {return arg0;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {int nHeadItemCount = mListHeadItemsName.size();ViewHolder viewHolder = null;View view = null;//内部类ViewHolder的作用只是用来查找ID,加载布局。提升效率的if (convertView == null) {viewHolder = new ViewHolder();view = mLayoutInflater.inflate(R.layout.layout_scroll_list_item, null);viewHolder.hscrollView = (MyHScrollView) view.findViewById(R.id.MyHScrollView_item);viewHolder.headIndex = (TextView)view.findViewById(R.id.textIndex);viewHolder.isSelectedCheckBox = (CheckBox) view.findViewById(R.id.checkBoxIsSelected);view.setTag(viewHolder);}else {view = convertView;viewHolder = (ViewHolder) view.getTag();}//合理分配横向滚动layout中textview的大小TextView lisTextView[] = new TextView[nHeadItemCount];LinearLayout layout_items = (LinearLayout)viewHolder.hscrollView.findViewById(R.id.layoutTextItems);layout_items.removeAllViews();for (int i = 0; i < nHeadItemCount; i++) {TextView text=new TextView(mContext);text.setGravity(Gravity.CENTER_VERTICAL); setTextParams(text, nHeadItemCount);layout_items.addView(text);lisTextView[i] = text;}//列表标题栏,序号数据装载setTextParams(viewHolder.headIndex, nHeadItemCount);viewHolder.headIndex.setText(String.valueOf(position));viewHolder.headIndex.setVisibility(mIsShowTextIndex == true ? View.VISIBLE : View.GONE);//每一项横向滚动数据的装载ArrayList<String> itemsData = getIndexDataArray(position);for(int i=0; i < nHeadItemCount;i++) {String value = itemsData.get(i);lisTextView[i].setText(value);}//多选checkbox的状态if (viewHolder.isSelectedCheckBox != null) {// 设置数据viewHolder.isSelectedCheckBox.setTag(position);viewHolder.isSelectedCheckBox.setVisibility(mItemsExtendData.get(position).mIsCheckBoxVisible == true ? View.VISIBLE: View.INVISIBLE);viewHolder.isSelectedCheckBox.setChecked(mItemsExtendData.get(position).mIsCheckBoxSelected);// 添加事件viewHolder.isSelectedCheckBox.setOnCheckedChangeListener(this);}//表头列表的滚动条事件添加到listview的每一项itemmHScrollView.AddOnScrollChangedListener(new OnScrollChangedListenerImp(viewHolder.hscrollView));return view;}@Overridepublic void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {Integer nPosition = (Integer)(buttonView.getTag());mItemsExtendData.get(nPosition.intValue()).mIsCheckBoxSelected = isChecked;}class OnScrollChangedListenerImp implements OnScrollChangedListener {MyHScrollView mScrollViewArg;public OnScrollChangedListenerImp(MyHScrollView scrollViewar) {mScrollViewArg = scrollViewar;}@Overridepublic void onScrollChanged(int l, int t, int oldl, int oldt) {mScrollViewArg.smoothScrollTo(l, t);}}}//listview的内部类static class ViewHolder {TextView headIndex;MyHScrollView hscrollView;CheckBox isSelectedCheckBox;}private class OnItemClickListener implements android.widget.AdapterView.OnItemClickListener{@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position,long id) {CheckBox isSelectedCheckBox = (CheckBox)view.findViewById(R.id.checkBoxIsSelected);if (mLongClickStatus) {//checkbox选择区域增强效果 isSelectedCheckBox.setChecked(!isSelectedCheckBox.isChecked()); return;}Integer nPosition = (Integer)(isSelectedCheckBox.getTag());Toast.makeText(getApplicationContext(), String.valueOf(nPosition), Toast.LENGTH_SHORT).show();}}private class OnItemLongClickListener implements android.widget.AdapterView.OnItemLongClickListener{@Overridepublic boolean onItemLongClick(AdapterView<?> parent, View view,int position, long id) {setCheckBoxStatue(true);return true;}}//控制listView checkbox控件的隐藏和显示protected void setCheckBoxStatue(boolean isVisible){if (isVisible) {for (ItemStatus ItemData: GetItemsExtendData()) {ItemData.mIsCheckBoxSelected = false;ItemData.mIsCheckBoxVisible = true;}}else {for (ItemStatus ItemData: GetItemsExtendData()) {ItemData.mIsCheckBoxSelected = false;ItemData.mIsCheckBoxVisible = false;}}mLongClickStatus = isVisible;mAdapter.notifyDataSetChanged();}@Overridepublic void finish(){if (mLongClickStatus) {setCheckBoxStatue(false);return;}super.finish();}//设置横向滚动中layout里面textview的宽度private void setTextParams(TextView textView, int col) {if (col == 0)return;textView.setMaxLines(1);textView.setTextSize(14);textView.setPadding(4, 0, 4, 0);textView.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);DisplayMetrics metric = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(metric);int basicScreenWidth = metric.widthPixels; // 屏幕宽度(像素)int basicScreenHeight = metric.heightPixels; // 屏幕高度(像素)int screenWidth = basicScreenWidth - dip2px(this, 60);if (col <= 3) {textView.setWidth(screenWidth / col + 20);} else {if (screenWidth > basicScreenHeight) {if (col > 5) {textView.setWidth(screenWidth / 5 + 10);} else {textView.setWidth(screenWidth / col + 10);}} else {textView.setWidth(screenWidth / 3 + 20);}}}public static int dip2px(Context context, float dpValue) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (dpValue * scale + 0.5f);}}
五、看看怎样使用上面那个类,MainActivity继承CustomListScrollManageActivity
package com.org.horizontalscrollview;import java.util.ArrayList;import android.os.Bundle;import android.view.View;import android.widget.AdapterView;import android.widget.Toast;public class MainActivity extends CustomListScrollManageActivity {private ArrayList<StudentItem> mList = new ArrayList<StudentItem>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);getDataSource();super.initView();} public ArrayList<StudentItem> getDataSource(){ for (int i = 0; i < 20; i++) { int j = i; StudentItem item1 = new StudentItem(j, "同学A", "男", 17, "高二"); mList.add(item1); j ++ ; StudentItem item2 = new StudentItem(j, "同学B", "女", 17, "高三"); mList.add(item2);} return mList; }@Overridepublic ArrayList<String> getReadListHeadItems() {ArrayList<String> headItems = new ArrayList<String>();headItems.add("学号");headItems.add("姓名");headItems.add("性别");headItems.add("年龄");headItems.add("年级");return headItems;}@Overridepublic ArrayList<String> getIndexDataArray(int recordIndex) {ArrayList<String> itemsData = new ArrayList<String>();StudentItem item = new StudentItem();item = mList.get(recordIndex);for (int i = 0; i <mList.size(); i++) {itemsData.add(String.valueOf(item.getmMunber()));itemsData.add(item.getmName());itemsData.add(item.getmSex());itemsData.add(String.valueOf(item.getmAge()));itemsData.add(item.getmGrade());}return itemsData;}@Overridepublic int getItemsCount() {return mList.size();}}
六、主要布局layout_common_sroll
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/layoutProgramManagerMainView" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:id="@+id/surfaceManagerListHead" android:layout_width="match_parent" android:layout_height="48dp" android:background="#F5FFFA" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:divider="@drawable/driver" android:paddingRight="10dp" android:showDividers="middle" > <TextView android:id="@+id/textIndex" android:layout_width="60dp" android:layout_height="match_parent" android:gravity="center_vertical" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="#218868" android:textSize="13dp" /> <com.org.scrollview.InterceptScrollContainer android:id="@+id/scroollContainter" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:focusable="false" > <com.org.scrollview.MyHScrollView android:id="@+id/MyHScrollView_head" android:layout_width="match_parent" android:layout_height="match_parent" android:focusable="false" android:scrollbars="none" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:id="@+id/layoutTextHeadItems" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:divider="@drawable/driver" android:focusable="false" android:gravity="center_vertical" android:orientation="horizontal" android:showDividers="middle" > </LinearLayout> </LinearLayout> </com.org.scrollview.MyHScrollView> </com.org.scrollview.InterceptScrollContainer> <FrameLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginRight="15dp" android:visibility="gone" > <CheckBox android:id="@+id/checkBoxIsSelected" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:visibility="invisible" /> </FrameLayout> </LinearLayout> </LinearLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ListView android:id="@+id/listViewCommonFeatureItems" android:layout_width="match_parent" android:layout_height="wrap_content" > </ListView> </LinearLayout> </RelativeLayout> </LinearLayout> </FrameLayout></LinearLayout>
这些选中的状态都有记下来了,后期你想怎么用就怎么用。到了这里就结束了,欢迎交流学习。
1 1
- Android 自定义横向滚动条
- Android 自定义横向滚动条联动进阶版
- 隐藏横向滚动条
- bootstrap横向滚动条
- DataTables自定义表格宽度(设置横向滚动条)
- 隐藏IE横向滚动条
- 去除框架横向滚动条
- frame去掉横向滚动条
- div纵向、横向滚动条
- 增加一个横向滚动条
- 去除框架横向滚动条
- 去掉iframe横向滚动条
- 横向滚动条的设置
- listbox 带横向滚动条
- 去除框架横向滚动条
- 去掉ie横向滚动条
- ListBox增加横向滚动条
- 隐藏CScrollView横向滚动条
- JVM 垃圾收集器及GC参数
- KL距离(二)(转)
- Java IO 之File操作
- http编程系列2:http协议GET方式获取网络图片
- 对C语言输入输出流和缓冲区的深入理解
- Android 自定义横向滚动条
- KL距离(三)(转)
- 快递100
- codeforces 432D D . Prefixes and Suffixes(后缀数组)
- pdf文档统计字数的问题
- StickyListHeaders
- 黑马程序员_JAVA单例设计模式
- Java容器总结
- 用友U9UBF刷枚举