前一段时间写了一个自定义横向滚动条,感觉效果不怎样好(
package com.org.scrollview;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.HorizontalScrollView;
/**
* @Description:这个类也是从网上找的参考
*/
public class SyncHorizontalScrollView extends HorizontalScrollView {
private View mView;
public SyncHorizontalScrollView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public SyncHorizontalScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
//设置控件滚动监听,得到滚动的距离,然后让传进来的view也设置相同的滚动具体
if(mView!=null) {
mView.scrollTo(l, t);
}
}
/**
* 设置跟它联动的view
* @param view
*/
public void setScrollView(View view) {
mView = view;
}
}
package com.org.horizontalscrollview;
import java.util.ArrayList;
import java.util.LinkedList;
import com.org.scrollview.SyncHorizontalScrollView;
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.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.ListAdapter;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.Toast;
public abstract class CustomListScrollManageActivity extends Activity{
//列表的标题
protected ArrayList mListHeadItemsName = new ArrayList();
//每一项checkbox的记录列表
protected LinkedList mItemsExtendData;
//列表整体标题栏滚动条
private SyncHorizontalScrollView mListHScrollView = null;
//是否显示第一列
protected boolean mIsShowTextIndex = true;
//listview的右边适配器
protected ListRightAdapter mRightAdapter;
//listview的左边适配器
protected ListLeftAdapter mLeftAdapter;
//处于长按状态true,不是长按状态false
protected boolean mLongClickStatus = false;
//右边的listview
protected ListView mrightListView;
//左边的listview
protected ListView mleftListView;
//整体的根布局
protected int mRootLayout = R.layout.layout_common_sroll;
//checkbox的状态
protected class ItemStatus {
public boolean mIsCheckBoxVisible = false;
public boolean mIsCheckBoxSelected = false;
}
//实例化每一项checkbox的记录列表mItemsExtendData
protected LinkedList GetItemsExtendData() {
if (mItemsExtendData == null) mItemsExtendData = new LinkedList();
return mItemsExtendData;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(mRootLayout);
}
//子类继承后初始化子类数据后,需要调用这个,初始化父类。
protected void initView() {
mListHScrollView = (SyncHorizontalScrollView) findViewById(R.id.listRightHScrollView);
SyncHorizontalScrollView listHeadHScrollView = (SyncHorizontalScrollView) findViewById(R.id.listHeadHScrollView);
//设置右边两个横向滚动条的联动滑动
mListHScrollView.setScrollView(listHeadHScrollView);
listHeadHScrollView.setScrollView(mListHScrollView);
mrightListView = (ListView)findViewById(R.id.rightListView);
mleftListView = (ListView)findViewById(R.id.leftListView);
//设置右边的监听事件
mrightListView.setOnItemClickListener(new OnItemClickListener());
mrightListView.setOnItemLongClickListener(new OnItemLongClickListener());
mListHeadItemsName = getReadListHeadItems();
mRightAdapter = new ListRightAdapter(this);
mrightListView.setAdapter(mRightAdapter);
mLeftAdapter = new ListLeftAdapter(this);
mleftListView.setAdapter(mLeftAdapter);
recreateHeadControl();
initCheckBoxVilible();
setCheckBoxStatue(false);
refreshListView();
}
//刷新列表
protected void refreshListView(){
//禁止了listview的自带的滚动,需要手动计算listview高度,使用滚动条栏滚动
SetListViewHeightBasedOnChildren(mleftListView);
SetListViewHeightBasedOnChildren(mrightListView);
mRightAdapter.notifyDataSetChanged();
mLeftAdapter.notifyDataSetChanged();
}
//加载表头列表数据
protected void recreateHeadControl() {
TextView headIndex = (TextView)findViewById(R.id.textIndex);
setTextParams(headIndex, mListHeadItemsName.size());
headIndex.setText("序号");
headIndex.setVisibility(mIsShowTextIndex == true?View.VISIBLE:View.GONE);
LinearLayout layout_items = (LinearLayout)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);
}
}
//初始化每一项的CheckBox
private void initCheckBoxVilible(){
GetItemsExtendData().clear();
for (int i = 0; i < getItemsCount(); i++) {
ItemStatus itemData = new ItemStatus();
// 插入队列
GetItemsExtendData().add(itemData);
}
}
//抽象接口,列表标题栏
public abstract ArrayList getReadListHeadItems();
//抽象接口,listview整体数据项
public abstract int getItemsCount();
/**
* 抽象接口,listview每一项数据的装载,装载返回是
* @param recordIndex
* @return ArrayList
*/
public abstract ArrayList getIndexDataArray(int recordIndex);
////////////////////////////////////////////////////////////
//需要每一项编辑或者增加,删除数据的抽象接口,请看具体情况自行添加
/**
* 左边的适配器
* @author Administrator
*
*/
public class ListLeftAdapter extends BaseAdapter{
private Context mContext;
private LayoutInflater mLayoutInflater;
public ListLeftAdapter(Context context) {
this.mContext = context;
mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return getItemsCount();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
View view = null;
//内部类ViewHolder的作用只是用来查找ID,加载布局。提升效率的
if (convertView == null) {
viewHolder = new ViewHolder();
view = mLayoutInflater.inflate(R.layout.layout_scroll_list_item_left, null);
viewHolder.headIndex = (TextView)view.findViewById(R.id.textIndex);
view.setTag(viewHolder);
}else {
view = convertView;
viewHolder = (ViewHolder) view.getTag();
}
//列表标题栏,序号数据装载
viewHolder.headIndex.setText(String.valueOf(position));
viewHolder.headIndex.setVisibility(mIsShowTextIndex == true ? View.VISIBLE : View.GONE);
return view;
}
}
/**
* 右边适配器
* @author Administrator
*
*/
public class ListRightAdapter extends BaseAdapter implements OnCheckedChangeListener {
private Context mContext;
private LayoutInflater mLayoutInflater;
public ListRightAdapter(Context context) {
this.mContext = context;
mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
Log.e("Show", String.valueOf(getItemsCount()));
return getItemsCount();
}
@Override
public Object getItem(int arg0) {
return null;
}
@Override
public long getItemId(int arg0) {
return arg0;
}
@Override
public 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_right, null);
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)view.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;
}
//每一项横向滚动数据的装载
ArrayList 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);
}
return view;
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Integer nPosition = (Integer)(buttonView.getTag());
mItemsExtendData.get(nPosition.intValue()).mIsCheckBoxSelected = isChecked;
}
}
//listview的内部类
private class ViewHolder {
TextView headIndex;
CheckBox isSelectedCheckBox;
}
private class OnItemClickListener implements android.widget.AdapterView.OnItemClickListener{
@Override
public 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{
@Override
public boolean onItemLongClick(AdapterView> parent, View view,int position, long id) {
setCheckBoxStatue(true);
if (mListHScrollView != null) {
mListHScrollView.post(new Runnable() {
public void run() {
mListHScrollView.fullScroll(ScrollView.FOCUS_RIGHT);
}
});
}
return false;
}
}
//控制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;
refreshListView();
}
@Override
public void finish(){
if (mLongClickStatus) {
setCheckBoxStatue(false);
return;
}
super.finish();
}
//手动计算listview的高度
private void SetListViewHeightBasedOnChildren(ListView listView) {
if (listView == null) return;
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) return;
int nTotalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
nTotalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = nTotalHeight + (listView.getDividerHeight()*(listAdapter.getCount()-1));
}
//设置横向滚动中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);
}
}
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 mList = new ArrayList();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getDataSource();
super.initView();
}
public ArrayList getDataSource(){
for (int i = 0; i < 20; i++) {
int j = i;
StudentItem item1 = new StudentItem(j, "同学A", "男", 18, "高二");
mList.add(item1);
j ++ ;
StudentItem item2 = new StudentItem(j, "同学B", "女", 17, "高三");
mList.add(item2);
}
return mList;
}
@Override
public ArrayList getReadListHeadItems() {
ArrayList headItems = new ArrayList();
headItems.add("学号");
headItems.add("姓名");
headItems.add("性别");
headItems.add("年龄");
headItems.add("年级");
return headItems;
}
@Override
public ArrayList getIndexDataArray(int recordIndex) {
ArrayList itemsData = new ArrayList();
StudentItem item = new StudentItem();
item = mList.get(recordIndex);
for (int i = 0; i
此外还有次要的两个listview的item的布局没贴出来,还有一个StudentItem的实体类没贴出来。欢迎留言评论!