左右上下联动滑动列表效果

device-2017-12-23-155908.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;
    }
}

接着去布局里面将控件摆放好,并给对应的列表设置适配器;



    

    

        

        

            

                
            

            
        

        

        

            

                
                

                
            
        
    

    

    

        

            

            

                
                
            

            

            

                

                    
                    
                
            
        
    


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 objects = parseMonthSale(readAssetsFile);
        if (objects != null && objects.size() != 0) {
            DataInfo object = (DataInfo) objects.get(0);
            List groupList = object.groupList;
            if (groupList == null)
                groupList = new ArrayList<>();
            topList.addAll(groupList);
            List 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 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 parseMonthSale(String data) {
        List list = new ArrayList();
        try {
            DataInfo info = new DataInfo();
            JSONObject itemJo = new JSONObject(data);
            JSONObject json = itemJo.getJSONObject("success");

            info.groupList = new ArrayList();
            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();
            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();
                    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 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

你可能感兴趣的:(左右上下联动滑动列表效果)