上面这个是左右上下联动滑动列表效果,其实就是左边一个列表可以上下滑动,右边一个列表可以上下左右滑动,然后再将左边列表和右边列表关联起来。
这里上下滑动用的是ListView和ScrollView,左右滑动用的是ListView和HorizontalScrollView,ListView和ScrollView及HorizontalScrollView会有冲突,首先要解决它们之间的冲突,ListView和ScrollView一起使用会造成ListView显示不全,可以自定义ListView重写它的onMeasure方法,也可以计算ListView条目的总高度,将总高度设值给ListView,这里采用的是计算ListView条目的总高度,不过需要注意的是ListView条目的总高度这个方法在父布局是LinearLayout的时候才会有效;ListView和HorizontalScrollView冲突解决是自定义HorizontalScrollView的方式;
public class SyncHorizontalScrollView extends HorizontalScrollView {
private View mView;
public SyncHorizontalScrollView(Context context) {
super(context);
}
public SyncHorizontalScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SyncHorizontalScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if(mView!=null) {
mView.scrollTo(l, t);
}
}
/**
*
* @param view
*/
public void setScrollView(View view) {
mView = view;
}
}
接着去布局里面将控件摆放好,并给对应的列表设置适配器;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private LinearLayout leftContainerView, rightContainerView, rightTopContainer;
private TextView tvCarModel;
private ListView leftListView;
private ListView rightListView;
private SyncHorizontalScrollView titleHorsv;
private SyncHorizontalScrollView contentHorsv;
private MyLeftAdapter leftAdapter;
private List leftlList = new ArrayList<>();
private MyRightAdapter myRightAdapter;
private List topList = new ArrayList<>();
private Map> rightMap = new HashMap<>();
private int screenW;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取屏幕的宽度
screenW = DensityUtil.getW(MainActivity.this);
rightTopContainer = (LinearLayout) findViewById(R.id.right_top_container);
pasentData();
initView();
}
private void initView() {
tvCarModel = (TextView) findViewById(R.id.tv_car_model);
tvCarModel.setTextSize(TypedValue.COMPLEX_UNIT_PX, DensityUtil.sp2px(MainActivity.this, 13f));
leftContainerView = (LinearLayout) findViewById(R.id.left_container);
//左边列表
leftListView = (ListView) findViewById(R.id.left_container_listview);
leftListView.setDivider(null);
rightContainerView = (LinearLayout) findViewById(R.id.right_container);
//右边列表
rightListView = (ListView) findViewById(R.id.right_container_listview);
rightListView.setDivider(null);
titleHorsv = (SyncHorizontalScrollView) findViewById(R.id.title_horsv);
contentHorsv = (SyncHorizontalScrollView) findViewById(R.id.content_horsv);
// 设置两个水平控件的联动
titleHorsv.setScrollView(contentHorsv);
contentHorsv.setScrollView(titleHorsv);
// 添加左边内容数据
leftContainerView.setBackgroundColor(Color.WHITE);
//左边列表数据适配器
leftAdapter = new MyLeftAdapter(MainActivity.this, leftlList);
leftListView.setAdapter(leftAdapter);
// 添加右边内容数据
rightContainerView.setBackgroundColor(Color.WHITE);
myRightAdapter = new MyRightAdapter(this, rightMap, topList, leftlList);
rightListView.setAdapter(myRightAdapter);
//设置左边和右边listview的高度
DensityUtil.setListViewHeightBasedOnChildren(rightListView);
DensityUtil.setListViewHeightBasedOnChildren(leftListView);
}
/**
* 根据组数据的多少创建textview
*/
private void getTextView() {
for (int i = 0; i < topList.size(); i++) {
TextView tv = new TextView(MainActivity.this);
tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, DensityUtil.sp2px(MainActivity.this, 13f));
tv.setGravity(Gravity.CENTER);// //此处相当于布局文件中的Android:gravity属性
tv.setTextColor(Color.parseColor("#000000"));
tv.setText("" + topList.get(i));
int w = 0;
if (topList.size() >= 4) {
w = DensityUtil.dip2px(MainActivity.this, 65);
} else {
w = (screenW - DensityUtil.dip2px(MainActivity.this, 80)) / topList.size();
}
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(w, LinearLayout.LayoutParams.MATCH_PARENT);
tv.setLayoutParams(params);// 设置圆点的大小
rightTopContainer.addView(tv);
}
}
/**
* 解析json数据
*/
private void pasentData() {
String readAssetsFile = readAssetsFile(MainActivity.this, "data/data.txt");
List
左边ListView的adapter
public class MyLeftAdapter extends BaseAdapter{
private Context context;
private List list;
public MyLeftAdapter(Context context, List list) {
super();
this.context = context;
this.list = new ArrayList();
if(list!=null)
{
this.list.addAll(list);
}
}
public void nodfiyData(List list){
if(list!=null)
{
this.list.clear();
this.list.addAll(list);
}
notifyDataSetChanged();
}
@Override
public int getCount() {
if (list!=null) {
return list.size();
}
return 0;
}
@Override
public Object getItem(int position) {
if (list!=null) {
return list.get(position);
}
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHold hold;
if (convertView==null) {
hold=new ViewHold();
convertView= LayoutInflater.from(context).inflate(R.layout.month_carmodel_left_item, null);
hold.textView=(TextView) convertView.findViewById(R.id.left_container_textview0);
hold.textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, DensityUtil.sp2px(context,13f));
convertView.setTag(hold);
}else {
hold=(ViewHold) convertView.getTag();
}
String string = list.get(position);
hold.textView.setText(""+string);
return convertView;
}
static class ViewHold{
TextView textView;
}
}
因为右边列表数据是动态变化的,所以右边item布局需要动态创建,根据实际获取到的数据进行创建;
public class MyRightAdapter extends BaseAdapter{
private Context context;
private List grouplist;
private List leftList;
private Map> rightMap;
private int timeSum=0;
public MyRightAdapter(Context context, Map> rightMap, List grouplist, List leftList) {
super();
this.context = context;
this.grouplist=grouplist;
this.leftList=leftList;
this.rightMap = new HashMap>();
if(rightMap!=null)
{
this.rightMap.putAll(rightMap);
}
}
public void nodfiyData(Map> rightMap){
if(rightMap!=null)
{
this.rightMap.clear();
this.rightMap.putAll(rightMap);
}
notifyDataSetChanged();
}
@Override
public int getCount() {
if (rightMap!=null) {
return rightMap.size();
}
return 0;
}
@Override
public Object getItem(int position) {
if (rightMap!=null) {
return rightMap.get(position);
}
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView==null) {
holder=new ViewHolder();
convertView= LayoutInflater.from(context).inflate(R.layout.layout_right_item, null);
holder.right_layout=(LinearLayout) convertView.findViewById(R.id.right_layout);
for (int i = 0; i < grouplist.size(); i++) {
long start = System.currentTimeMillis();
TextView tv = new TextView(context);
tv.setTextSize(TypedValue.COMPLEX_UNIT_PX,DensityUtil.sp2px(context,13f));
tv.setGravity(Gravity.CENTER);// //此处相当于布局文件中的Android:gravity属性
tv.setTextColor(context.getResources().getColor(R.color.black));
String string = leftList.get(position);
List list = rightMap.get(string);
String string2 = list.get(i);
if (string2==null||string2.length()==0) {
string2="0";
}
tv.setText("" +string2 );
int w=0;
if (grouplist.size()>=4) {
w= DensityUtil.dip2px(context,65);
}else{
w=(DensityUtil.getW(context)-DensityUtil.dip2px(context,80))/grouplist.size();
}
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(w,
LinearLayout.LayoutParams.MATCH_PARENT);
tv.setLayoutParams(params);
holder.right_layout.addView(tv);
long end = System.currentTimeMillis();
long time = end - start;
timeSum+=time;
}
convertView.setTag(holder);
}else{
holder=(ViewHolder) convertView.getTag();
}
System.out.println("--------------timeSum" + timeSum);// 5002 5244 154 117 212
return convertView;
}
class ViewHolder{
LinearLayout right_layout;
}
}
源码地址:
https://pan.baidu.com/s/1boP8q9D