今天折腾了半天自定义控件的问题,如下图所示,我们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. everything 提供http和ftp的功能

    1. 早上起床看知乎,发现everything 有http和ftp的功能, 简单看了一下的确很强大.. 就是有点危险.. 功能位置. 2. 最下面有FTP和HTTP 可以进行启用 这是http的 建议 ...

  2. SpringBoot 1.快速搭建一个 SpringBoot Maven工程

    一.新建一个Maven工程 (1)选择创建简单MAVNE工程 (2)输入你自己的MAVEN工程的Group Id(必填).Artifact Id(必填).Version(必填).Packaging(必 ...

  3. 在手机上点击input框时会放大页面

    加上  <meta name="viewport" content="initial-scale=1.0, minimum-scale=1.0, maximum-s ...

  4. 【Vue学习笔记1】全局配置 Vue.config

    1.slient 类型:boolean: 默认:false: 用法:Vue.config.silent = true  用于取消 Vue 所有的日志与警告

  5. MT【86】两个绝对值之和最大

    分析:这里只需要注意到$(|x|+|y|)_{max}=max\{|x+y|,|x-y|\}$,所以只需求$max\{|20a|,|14b|\}$ 进而变成熟悉的反解系数问题.容易知道最大值为$a=2 ...

  6. 【题解】 bzoj1597: [Usaco2008 Mar]土地购买 (动态规划+斜率优化)

    bzoj1597懒得复制,戳我戳我 Solution: 线性DP打牌\(+\)斜率优化 定义状态:\(dp[i]\)到了位置\(i\)最少花费 首先我们要发现,如果有一个小方块能被其他的大方块包围,其 ...

  7. 【BZOJ1044】[HAOI2008]木棍分割(动态规划,贪心)

    [BZOJ1044][HAOI2008]木棍分割(动态规划,贪心) 题面 BZOJ 洛谷 题解 第一问随便二分一下就好了,贪心\(check\)正确性显然. 第二问随便前缀和+单调队列优化一下\(dp ...

  8. Installshield 打包安装程序时写入注册表,及运行bat文件

    一.写入注册表 1. 打开project assistant –> Project Registry 可以像注册表里一样操作,其中[INSTALLDIR]是指的安装路径   二. 运行bat文件 ...

  9. 【bzoj1030】 JSOI2007—文本生成器

    http://www.lydsy.com/JudgeOnline/problem.php?id=1030 (题目链接) 题意 给出$n$个单词,问有多少个长度为$m$的文本中至少包含一个单词. Sol ...

  10. 「Django」contenttypes基本用法

    当一张表和多个表ForeignKey关联,并且多个FK中只能选择其中一个或其中n个时,可以利用contenttypes,只需定义三个字段就搞定! contenttypes 是Django内置的一个应用 ...