今天折腾了半天自定义控件的问题,如下图所示,我们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);
}
}

(原创)关于viewpager嵌套listview居中显示的问题的更多相关文章

  1. 解决lScrollView嵌套ListView只显示一行的问题,listvie显示全部的item

    ScrollView嵌套ListView只显示一行的问题 1.思路:给listview重新添加一个高度. listview的高度==listview.item的高度之和. 2.注意:关键是添加list ...

  2. ScrollView嵌套ListView只显示一行之计算的高度不正确的解决办法(转)

    ScrollView嵌套ListView只显示一行之计算的高度不正确的解决办法 分类: android应用开发2013-12-19 09:40 1045人阅读 评论(3) 收藏 举报 AndroidS ...

  3. 一键解决ScrollView嵌套ListView仅仅显示一行的问题

    /** * 解决ScrollView嵌套ListView仅仅显示一行的问题 * * @param listView */ private void setListViewHeightBasedOnCh ...

  4. WPF ListView 居中显示

    原文:WPF ListView 居中显示 今天遇到的问题: 方法1:设置GridViewColumn的ActualWidth <ListView > <ListView.View&g ...

  5. 冲突--ScrollView嵌套ListView只显示一行

    在开发的过程当中,由于手机屏幕的大小的限制,我们经常需要使用滑动的方式,来显示更多的内容.在最近的工作中,遇见一个需求,需要将ListView嵌套到ScrollView中显示.于是乎有了如下布局: & ...

  6. 日积月累:ScrollView嵌套ListView只显示一行

    在开发的过程当中,由于手机屏幕的大小的限制,我们经常需要使用滑动的方式,来显示更多的内容.在最近的工作中,遇见一个需求,需要将ListView嵌套到ScrollView中显示.于是乎有了如下布局: & ...

  7. ScrollView嵌套ListView只显示一行

    错误描述 ScrollView嵌套ListView中导致ListView高度计算不正确,只显示一行. 解决方法 重写ListView的onMeasure方法,代码如下. @Override publi ...

  8. 安卓开发ScrollView嵌套ListView只显示一行

    在用列表控件做一个“更多功能”的界面的时候 <?xml version="1.0" encoding="utf-8"?> <ScrollVie ...

  9. ScrollView嵌套ListView只显示一行解决方案

    在ScrollView里边嵌套了个ListView,后边就发现数据源里好多数据,但ListView只是显示1行. 各种debug,打log,数据什么的都没问题,上网百度了下,发现原来是ScrollVi ...

随机推荐

  1. Restful api 防止重复提交

    当前很多网站是前后分离的,前端(android,iso,h5)通过restful API 调用 后端服务器,这就存在一个问题,对于创建操作,比如购买某个商品,如果由于某种原因,手抖,控件bug,网络错 ...

  2. 三星a9上测试egret与pixi.js的渲染性能

    for (let i = 0; i < 500; i++) { let shape = new egret.Shape(); shape.graphics.beginFill(0xff0000) ...

  3. Servlet 生命周期、工作原理-是单实例多线程

    Servelet是单实例多线程的 参考:servlet单实例多线程模式 一.Servlet生命周期 大致分为4部:Servlet类加载-->实例化-->服务-->销毁 1.Web C ...

  4. 返回通知的方法 是void

  5. BZOJ4520 CQOI2016K远点对(KD-Tree+堆)

    堆维护第k大,每个点KD-Tree上A*式查询较远点,跑得飞快,复杂度玄学. #include<iostream> #include<cstdio> #include<c ...

  6. hdwiki 参考资料改成可点击跳转的(默认不能点)

    (1)首先在view这个文件夹找到viewdoc.htm文件.(2)在viewdoc.htm源码中搜索“<dd> <span>[{eval echo ($i+1)}]”找到下面 ...

  7. 目标检测评价指标(mAP)

    常见指标 precision 预测出的所有目标中正确的比例 (true positives / true positives + false positives). recall 被正确定位识别的目标 ...

  8. First non-repeating character in a stream

    First non-repeating character in a stream Given an input stream of n characters consisting only of s ...

  9. IAR ------ 基本使用

    1.编译结果: 6 887 bytes of readonly code memory 621 bytes of readonly data memory 331 bytes of readwrite ...

  10. tp3 链接生成二维码

    https://packagist.org/packages/endroid/qr-code