![](https://img.haomeiwen.com/i5186985/14f608afa7cffe75.gif)
上面这个是左右上下联动滑动列表效果,其实就是左边一个列表可以上下滑动,右边一个列表可以上下左右滑动,然后再将左边列表和右边列表关联起来。
这里上下滑动用的是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;
}
}
接着去布局里面将控件摆放好,并给对应的列表设置适配器;
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/farther_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- 此部分是标题部分 -->
<LinearLayout
android:id="@+id/top_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="visible" >
<!-- 左侧标题的父容器 -->
<LinearLayout
android:id="@+id/left_title_container"
android:layout_width="@dimen/month_car_model_width"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:layout_width="@dimen/month_car_model_width"
android:layout_height="@dimen/list_item_height"
android:gravity="center"
android:orientation="vertical" >
<TextView
android:id="@+id/tv_car_model"
android:layout_width="@dimen/month_car_model_width"
android:layout_height="@dimen/list_item_height"
android:gravity="center"
android:maxLines="1"
android:text="data"
android:textSize="13sp" />
</LinearLayout>
<View style="@style/lineStyle"
android:id="@+id/title_line"/>
</LinearLayout>
<!-- 右侧标题的父容器可实现水平滚动 -->
<com.list.listapplication.com.list.listapplication.widget.SyncHorizontalScrollView
android:id="@+id/title_horsv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:scrollbars="none" >
<LinearLayout
android:id="@+id/right_title_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/right_top_container"
android:layout_width="wrap_content"
android:layout_height="@dimen/list_item_height"
android:background="@color/white"
android:orientation="horizontal" >
</LinearLayout>
<View style="@style/lineStyle" />
</LinearLayout>
</com.list.listapplication.com.list.listapplication.widget.SyncHorizontalScrollView>
</LinearLayout>
<!-- 此部分是内容部分 用ScrollView实现上下滚动效果 -->
<ScrollView
android:id="@+id/car_scrollview"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- 左侧内容的父容器 -->
<LinearLayout
android:id="@+id/left_container"
android:layout_width="@dimen/month_car_model_width"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical"
android:visibility="visible" >
<ListView
android:id="@+id/left_container_listview"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</LinearLayout>
<!-- 右侧内容的父容器 实现水平滚动 -->
<com.list.listapplication.com.list.listapplication.widget.SyncHorizontalScrollView
android:id="@+id/content_horsv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:scrollbars="none" >
<LinearLayout
android:id="@+id/right_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal" >
<ListView
android:id="@+id/right_container_listview"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</LinearLayout>
</com.list.listapplication.com.list.listapplication.widget.SyncHorizontalScrollView>
</LinearLayout>
</ScrollView>
</LinearLayout>
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<String> leftlList = new ArrayList<>();
private MyRightAdapter myRightAdapter;
private List<String> topList = new ArrayList<>();
private Map<String, List<String>> 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<Object> objects = parseMonthSale(readAssetsFile);
if (objects != null && objects.size() != 0) {
DataInfo object = (DataInfo) objects.get(0);
List<String> groupList = object.groupList;
if (groupList == null)
groupList = new ArrayList<>();
topList.addAll(groupList);
List<DataInfo> saleList = object.saleList;
if (saleList == null) {
saleList = new ArrayList<>();
}
if (saleList != null && saleList.size() != 0) {
for (int i = 0; i < saleList.size(); i++) {
DataInfo dtGzsHome = saleList.get(i);
String data_type = dtGzsHome.data_type;
leftlList.add(data_type);
List<String> dataList = dtGzsHome.dataList;
if (dataList == null) {
dataList = new ArrayList<>();
}
rightMap.put(data_type, dataList);
}
}
}
System.out.println("---------rightMap" + rightMap.size());
if (topList.size() != 0) {
// 根据组数据的多少创建textview
getTextView();
}
}
/**
* 获取程序中Assets文件底下的文件txt
*
* @param context 上下文
* @param fileName 文件名称
* @return txt文本的字符串
*/
private String readAssetsFile(Context context, String fileName) {
String res = "";
try {
// 得到资源中的asset数据流
InputStream in = context.getResources().getAssets().open(fileName);
res = readTextFromSDcard(in);
} catch (Exception e) {
Log.e(TAG, "");
}
return res;
}
/**
* 按行读取txt
*
* @param is
* @return
* @throws Exception
*/
private String readTextFromSDcard(InputStream is) throws Exception {
InputStreamReader reader = new InputStreamReader(is);
BufferedReader bufferedReader = new BufferedReader(reader);
StringBuffer buffer = new StringBuffer("");
String str;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
buffer.append("\n");
}
return buffer.toString();
}
private static List<Object> parseMonthSale(String data) {
List<Object> list = new ArrayList<Object>();
try {
DataInfo info = new DataInfo();
JSONObject itemJo = new JSONObject(data);
JSONObject json = itemJo.getJSONObject("success");
info.groupList = new ArrayList<String>();
boolean null3 = json.isNull("group_list");
if (!null3) {
JSONArray group_list = json.getJSONArray("group_list");
for (int i = 0; i < group_list.length(); i++) {
String string = group_list.getString(i);
info.groupList.add(string);
}
}
info.saleList = new ArrayList<DataInfo>();
boolean null1 = json.isNull("datas");
if (!null1) {
JSONArray dataArray = json.getJSONArray("datas");
for (int i = 0; i < dataArray.length(); i++) {
JSONObject jsonObject = dataArray.getJSONObject(i);
DataInfo vo = new DataInfo();
vo.CLASSES_ID = parseString("CLASSES_ID", jsonObject);
vo.data_type = parseString("data_type", jsonObject);
vo.dataList = new ArrayList<String>();
boolean null2 = jsonObject.isNull("group_datas");
if (!null2) {
JSONArray array = jsonObject.getJSONArray("group_datas");
for (int j = 0; j < array.length(); j++) {
String object = (String) array.getString(j);
vo.dataList.add(object);
}
}
info.saleList.add(vo);
}
}
list.add(info);
} catch (JSONException e) {
e.printStackTrace();
return null;
}
return list;
}
public static String parseString(String key, JSONObject json) {
if (json.isNull(key)) {
return "";
} else {
try {
return json.getString(key);
} catch (JSONException e) {
e.printStackTrace();
return "";
}
}
}
}
左边ListView的adapter
public class MyLeftAdapter extends BaseAdapter{
private Context context;
private List<String> list;
public MyLeftAdapter(Context context, List<String> list) {
super();
this.context = context;
this.list = new ArrayList<String>();
if(list!=null)
{
this.list.addAll(list);
}
}
public void nodfiyData(List<String> 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<String> grouplist;
private List<String> leftList;
private Map<String,List<String>> rightMap;
private int timeSum=0;
public MyRightAdapter(Context context, Map<String,List<String>> rightMap, List<String> grouplist, List<String> leftList) {
super();
this.context = context;
this.grouplist=grouplist;
this.leftList=leftList;
this.rightMap = new HashMap<String,List<String>>();
if(rightMap!=null)
{
this.rightMap.putAll(rightMap);
}
}
public void nodfiyData(Map<String,List<String>> 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<String> 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;
}
}
网友评论