zoukankan      html  css  js  c++  java
  • (原创)关于viewpager嵌套listview居中显示的问题

    今天折腾了半天自定义控件的问题,如下图所示,我们UI设计了一种可以左右滑动的列表,而列表中又包含了listview。而且要居中显示listview

    我一看UI,心想简单,不就是根据datas的数目进行分页么,有几页就在viewpager里add几个listview,然后设置viewpager居中显示不就行了么?

    这里先设置viewpager的width为wrap_content,listview的width也是wrap_content。然后根据数据分页,填充数据,设置页数指示点。

    结果一运行发现问题所在,所有的条目都居左显示,而且viewpager一点也没有wrap_content,全都是占满了屏幕!

    于是我就开始继承viewpager后自定义viewpager,让viewpager的宽度自动修改为子view中最大的宽度,结果发现不论怎么改,依然还是全屏!

    后来才怀疑到是listview的问题,把listview弄出来设置wrap_content,结果一运行果然还是全屏!

    于是乎又开始了自定义listview之旅,终于把这一切都自定义好了,然后一运行,果然第一页的内容宽度自适应了!,也居中显示了。

    然而坑就坑在这里了,向左滑动下一页的宽度和这一页不一样,结果就又偏左了,再翻到第三页就居中了,也变窄了,结果划回来宽度就是后边的小宽度了。

    如此坑爹啊!

    后来终于想到一种办法就是,去掉viewpager的宽度自适应,让其match_parent,然后在listview的外城包裹一个LinearLayout,让LinearLayout实现match_parent,然后listview自适应宽度,并在LinearLayout中居中显示。

    后边的代码如下:

    item_list_address.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:orientation="horizontal">
    
        <TextView
            android:id="@+id/tv_address_number"
            style="@style/YunNormalText"
            android:layout_width="@dimen/x100"
            android:layout_height="@dimen/x100"
            android:layout_gravity="center_vertical"
            android:background="@drawable/shape_circle_blue"
            android:gravity="center"
            android:text="1"
            android:textColor="@color/YunCircleBlue"/>
    
        <LinearLayout
            android:id="@+id/ll_item_background"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/x90"
            android:background="@drawable/ic_item_background"
            android:minWidth="@dimen/x800"
            android:orientation="vertical">
    
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
    
                <TextView
                    android:id="@+id/tv_address_title"
                    style="@style/YunNormalText"
                    android:text="回龙观(地铁站)"/>
    
                <TextView
                    android:id="@+id/tv_address_distance"
                    style="@style/YunNormalText"
                    android:text="14.7公里"/>
            </LinearLayout>
    
    
            <TextView
                android:id="@+id/tv_address_des"
                style="@style/YunSmallText"
                android:text="13号线"/>
        </LinearLayout>
    </LinearLayout>

    layout_listview.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:gravity="center|top"
                  android:orientation="horizontal">
    
        <com.honghe.library.view.WrapContentListView
    
            android:id="@+id/lv_address"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:listSelector="@android:color/transparent">
    
        </com.honghe.library.view.WrapContentListView>
    </LinearLayout>

    fragment_addresses.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">
    
        <ImageView
            android:id="@+id/iv_back"
            android:layout_width="@dimen/x60"
            android:layout_height="@dimen/x60"
            android:layout_marginLeft="@dimen/x75"
            android:layout_marginTop="@dimen/y135"
            android:src="@drawable/ic_back"/>
    
        <com.honghe.library.view.VoiceRobotStatusView
            android:id="@+id/vrsv_3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/x470"
            android:layout_marginTop="@dimen/y120"/>
    
        <TextView
            android:id="@+id/tv_voice_search_hint"
            style="@style/YunNormalText"
            android:layout_width="@dimen/x762"
            android:layout_marginLeft="@dimen/x690"
            android:layout_marginTop="@dimen/y100"
            android:text="金贸大厦"
            android:textAlignment="center"/>
    
        <ImageView
            android:layout_width="@dimen/x762"
            android:layout_height="@dimen/y3"
            android:layout_below="@+id/tv_voice_search_hint"
            android:layout_marginLeft="@dimen/x690"
            android:src="@drawable/ic_light_line"/>
    
        <TextView
            style="@style/YunSmallText"
            android:layout_below="@+id/tv_voice_search_hint"
            android:layout_marginLeft="@dimen/x690"
            android:text="找到9个结果,请说第几个/下一页/取消"
            android:textSize="@dimen/y40"/>
    
        <android.support.v4.view.ViewPager
            android:id="@+id/vp_address"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="@dimen/y300"
            android:visibility="visible">
    
        </android.support.v4.view.ViewPager>
    
        <LinearLayout
            android:id="@+id/ll_dots"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="@dimen/y100"
            android:orientation="horizontal">
    
        </LinearLayout>
    
    </RelativeLayout>

    WrapContentListView.java

    package com.honghe.library.view;
    
    import android.content.Context;
    import android.os.Build;
    import android.support.annotation.RequiresApi;
    import android.util.AttributeSet;
    import android.view.View;
    import android.widget.ListView;
    
    /**
     * Created by wanghh on 2017/5/11.
     */
    
    public class WrapContentListView extends ListView {
        public WrapContentListView(Context context) {
            super(context);
        }
    
        public WrapContentListView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public WrapContentListView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        public WrapContentListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int width = getMaxWidthOfChildren() + getPaddingLeft() + getPaddingRight();//计算listview的宽度
            super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), heightMeasureSpec);//设置listview的宽高
        }
    
        /**
         * 计算item的最大宽度
         *
         * @return
         */
        private int getMaxWidthOfChildren() {
            int maxWidth = 0;
            View view = null;
            int count = getAdapter().getCount();
            for (int i = 0; i < count; i++) {
                view = getAdapter().getView(i, view, this);
                view.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
                if (view.getMeasuredWidth() > maxWidth)
                    maxWidth = view.getMeasuredWidth();
            }
            if (maxWidth > getContext().getResources().getDisplayMetrics().widthPixels) {
                maxWidth = getContext().getResources().getDisplayMetrics().widthPixels;
            }
            return maxWidth;
        }
    }
    AddressesFragment.java
    package com.yunjia.hud.fragment;
    
    import android.content.Context;
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.v4.view.ViewPager;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.ListView;
    
    import com.amap.api.services.core.LatLonPoint;
    import com.amap.api.services.core.PoiItem;
    import com.honghe.library.view.VoiceRobotStatusView;
    import com.yunjia.hud.R;
    import com.yunjia.hud.adapter.AddressAdapter;
    import com.yunjia.hud.adapter.ViewPagerListAdapter;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import me.yokeyword.fragmentation.SupportFragment;
    
    /**
     * Created by wanghh on 2017/5/11.
     */
    
    public class AddressesFragment extends SupportFragment implements View.OnClickListener {
        private Context mContext;
        private static final String TAG = AddressesFragment.class.getName();
        private View rootView;
        private VoiceRobotStatusView vrsv_3;
        private ViewPager vp_address;
        private LinearLayout ll_dots;
        private List<ImageView> mDots;
    
        public static AddressesFragment newInstance() {
            return new AddressesFragment();
        }
    
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            if (rootView == null) {
                rootView = inflater.inflate(R.layout.fragment_addresses, container, false);
            }
            initView();
            setData();
            setListener();
            return rootView;
        }
    
        private void initView() {
            vrsv_3 = (VoiceRobotStatusView) rootView.findViewById(R.id.vrsv_3);
            vp_address = (ViewPager) rootView.findViewById(R.id.vp_address);
            ll_dots = (LinearLayout) rootView.findViewById(R.id.ll_dots);
        }
    
        private void setData() {
    //模拟数据
            List<PoiItem> poiItems = new ArrayList<>();
            for (int i = 0; i < 11; i++) {
                if (i < 3) {
                    PoiItem poiItem = new PoiItem("哈哈" + i, new LatLonPoint(0.0, 0.0), "哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈" + i, "呵呵" + i);
                    poiItems.add(poiItem);
                } else {
                    PoiItem poiItem2 = new PoiItem("哈哈" + i, new LatLonPoint(0.0, 0.0), "哈哈" + i, "呵呵" + i);
                    poiItems.add(poiItem2);
                }
            }
            setViewPagerData(poiItems);
        }
    
        private void setListener() {
            vrsv_3.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.vrsv_3:
                    vrsv_3.switchView();
                    break;
            }
        }
    
        private void setViewPagerData(List<PoiItem> datas) {
            List<View> views = new ArrayList<>();
            int split = 3;
            int totalNumber = datas.size();
            int pages = totalNumber % split == 0 ? totalNumber / split : totalNumber / split + 1;
            initPoints(pages);
            for (int i = 0; i < pages; i++) {
                View view = LayoutInflater.from(getActivity()).inflate(R.layout.layout_listview, null);
                ListView listView = (ListView) view.findViewById(R.id.lv_address);
                List<PoiItem> poiItems = new ArrayList<>();
                int numOfPoiItemsPerPage = (totalNumber - split * i) / split == 0 ? (totalNumber - split * i) % split : split;
                for (int j = 0; j < numOfPoiItemsPerPage; j++) {
                    poiItems.add(datas.get(split * i + j));
                }
                AddressAdapter adapter = new AddressAdapter(getActivity());
                listView.setAdapter(adapter);
                adapter.setData(poiItems);
                views.add(view);
            }
            vp_address.setAdapter(new ViewPagerListAdapter(views));
            vp_address.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                @Override
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    
                }
    
                @Override
                public void onPageSelected(int position) {
                    updatePoints(position);
                }
    
                @Override
                public void onPageScrollStateChanged(int state) {
    
                }
            });
        }
    
        private void initPoints(int pageSize) {
            ll_dots.removeAllViews();
            mDots = new ArrayList<>();
            ImageView imageView;
            for (int i = 0; i < pageSize; i++) {
                imageView = new ImageView(getActivity());
                imageView.setBackgroundResource(R.drawable.ic_dot_unselected);
                LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
                        new ViewGroup.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                                LinearLayout.LayoutParams.WRAP_CONTENT));
                layoutParams.leftMargin = 10;
                layoutParams.rightMargin = 10;
                ll_dots.addView(imageView, layoutParams);
                if (i == 0) {
                    imageView.setBackgroundResource(R.drawable.ic_dot_selected);
                }
                mDots.add(imageView);
            }
        }
    
        private void updatePoints(int index) {
            for (int i = 0; i < mDots.size(); i++) {
                if (index == i) {
                    mDots.get(i).setBackgroundResource(R.drawable.ic_dot_selected);
                } else {
                    mDots.get(i).setBackgroundResource(R.drawable.ic_dot_unselected);
                }
            }
        }
    }

    AddressAdapter.java

    package com.yunjia.hud.adapter;
    
    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    
    import com.amap.api.maps.AMapUtils;
    import com.amap.api.maps.model.LatLng;
    import com.amap.api.services.core.PoiItem;
    import com.honghe.library.util.AMapUtil;
    import com.honghe.library.util.ConstUtil;
    import com.yunjia.hud.R;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * Created by wanghh on 2017/5/11.
     */
    
    public class AddressAdapter extends BaseAdapter {
        private Context mContext;
        private List<PoiItem> mDatas = new ArrayList<>();
        private int position;
    
        public AddressAdapter(Context context) {
            this.mContext = context;
        }
    
        public void setData(List<PoiItem> datas) {
            if (null != datas && datas.size() > 0) {
                this.mDatas.clear();
                this.mDatas.addAll(datas);
            }
            notifyDataSetChanged();
        }
    
        @Override
        public int getCount() {
            if (null != mDatas) {
                return mDatas.size();
            }
            return 0;
        }
    
        @Override
        public Object getItem(int position) {
            return mDatas.get(position);
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        public void selectItem(int position) {
            this.position = position;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder;
            if (convertView == null) {
                convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list_address, null);
                viewHolder = new ViewHolder();
                viewHolder.ll_item_background = (LinearLayout) convertView.findViewById(R.id.ll_item_background);
                viewHolder.tv_address_number = (TextView) convertView.findViewById(R.id.tv_address_number);
                viewHolder.tv_address_title = (TextView) convertView.findViewById(R.id.tv_address_title);
                viewHolder.tv_address_distance = (TextView) convertView.findViewById(R.id.tv_address_distance);
                viewHolder.tv_address_des = (TextView) convertView.findViewById(R.id.tv_address_des);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }
            switch (position % 3) {
                case 0:
                    viewHolder.tv_address_number.setTextColor(mContext.getResources().getColor(R.color.YunCircleBlue));
                    viewHolder.tv_address_number.setBackgroundResource(R.drawable.shape_circle_blue);
                    break;
                case 1:
                    viewHolder.tv_address_number.setTextColor(mContext.getResources().getColor(R.color.YunCircleGreen));
                    viewHolder.tv_address_number.setBackgroundResource(R.drawable.shape_circle_green);
                    break;
                case 2:
                    viewHolder.tv_address_number.setTextColor(mContext.getResources().getColor(R.color.YunCircleYellow));
                    viewHolder.tv_address_number.setBackgroundResource(R.drawable.shape_circle_yellow);
                    break;
            }
            if (position == this.position) {
                viewHolder.ll_item_background.setSelected(true);
            } else {
                viewHolder.ll_item_background.setSelected(false);
            }
            viewHolder.tv_address_number.setText("" + (position + 1));
            viewHolder.tv_address_title.setText(mDatas.get(position).getTitle());
            viewHolder.tv_address_distance.setText(AMapUtil.getLengthString((int) AMapUtils.calculateLineDistance(new LatLng(ConstUtil.currentLatitude, ConstUtil.currentLongitude), new LatLng(mDatas.get(position).getLatLonPoint().getLatitude(), mDatas.get(position).getLatLonPoint().getLongitude()))));
            viewHolder.tv_address_des.setText(mDatas.get(position).getSnippet());
            return convertView;
        }
    
        private class ViewHolder {
            LinearLayout ll_item_background;
            TextView tv_address_number;
            TextView tv_address_title;
            TextView tv_address_distance;
            TextView tv_address_des;
        }
    }

    ViewPagerListAdapter.java

    package com.yunjia.hud.adapter;
    
    import android.support.v4.view.PagerAdapter;
    import android.support.v4.view.ViewPager;
    import android.view.View;
    import android.view.ViewGroup;
    
    import java.util.List;
    
    /**
     * Created by wanghh on 2017/5/11.
     */
    
    public class ViewPagerListAdapter extends PagerAdapter {
        private List<View> pageViews;
    
        public ViewPagerListAdapter(List<View> pageViews) {
            super();
            this.pageViews = pageViews;
        }
    
        @Override
        public int getCount() {
            if (null != pageViews) {
                return pageViews.size();
            }
            return 0;
        }
    
        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }
    
        @Override
        public int getItemPosition(Object object) {
            return super.getItemPosition(object);
        }
    
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            ((ViewPager) container).removeView(pageViews.get(position));
        }
    
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            ((ViewPager) container).addView(pageViews.get(position));
            return pageViews.get(position);
        }
    }
  • 相关阅读:
    Delphi 7下使用VT实现树型列表结合控件
    Spring:源码解读Spring IOC原理
    【HTTP】Fiddler(二)
    简单工厂模式、工厂方法模式、抽象工厂模式 之间的对比
    UML类图关系(泛化 、继承、实现、依赖、关联、聚合、组合)
    Tomcat 的context.xml
    Tomcat的context.xml说明、Context标签讲解
    Node.js
    区块链架构设计
    什么是区块链
  • 原文地址:https://www.cnblogs.com/dongweiq/p/6842575.html
Copyright © 2011-2022 走看看