标签:
最近项目有一个需求,需要多层可滑动控件的嵌套展示,demo效果如下,demo的下载地址在最后
咋一看好像挺简单啊,不就是一个ScrollView + ViewPager + ListView吗,我开始也这样觉得,也用的这种方式实现,结果始终和效果不对劲。这里总结几点问题:
<?xml version="1.0" encoding="utf-8"?> <ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent" android:cacheColorHint="@android:color/transparent" android:divider="@null" android:dividerHeight="0dp" android:listSelector="@android:color/transparent" />
public class MainActivity extends FragmentActivity { private TabPageIndicator indicator; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ListView listView = (ListView) findViewById(R.id.listView); View header = View.inflate(this, R.layout.header, null); indicator = (TabPageIndicator) header.findViewById(R.id.indicator); listView.addHeaderView(header); listView.setAdapter(new CustomAdapter(this)); } public class CustomAdapter extends BaseAdapter{ private View view; private WrapContentViewPager viewPager; public CustomAdapter(Context context) { view = View.inflate(context, R.layout.item_main, null); viewPager = (WrapContentViewPager) view.findViewById(R.id.viewPager); viewPager.setAdapter(new ListFragmentAdapter(viewPager, getSupportFragmentManager())); indicator.setViewPager(viewPager); viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { viewPager.resetHeight(position); indicator.setCurrentItem(position); } @Override public void onPageScrollStateChanged(int state) { } }); viewPager.resetHeight(0); } @Override public int getCount() { return 1; } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { return view; } } }
<?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="wrap_content" android:orientation="vertical" > <TextView android:layout_width="match_parent" android:layout_height="80dp" android:gravity="center" android:background="@android:color/holo_red_light" android:text="Hello World!" /> <TextView android:layout_width="match_parent" android:layout_height="80dp" android:gravity="center" android:background="@android:color/holo_blue_light" android:text="Hello World!" /> <TextView android:layout_width="match_parent" android:layout_height="80dp" android:gravity="center" android:background="@android:color/holo_orange_light" android:text="Hello World!" /> <TextView android:layout_width="match_parent" android:layout_height="80dp" android:gravity="center" android:background="@android:color/holo_green_light" android:text="Hello World!" /> <cc.wxf.androiddemo.indicator.TabPageIndicator android:id="@+id/indicator" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>这儿的header只包含了一些TextView作为demo展示,然后包含了导航控件Indicator。接着是ListView唯一一项Item的布局文件item_main.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="wrap_content"> <cc.wxf.androiddemo.WrapContentViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>
package cc.wxf.androiddemo; import android.content.Context; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.widget.LinearLayout; import java.util.HashMap; import java.util.Map; public class WrapContentViewPager extends ViewPager { private Map<Integer, Integer> maps = new HashMap<Integer, Integer>(); private int current; public WrapContentViewPager(Context context, AttributeSet attrs) { super(context, attrs); } public WrapContentViewPager(Context context) { super(context); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int height = 0; if(maps.size() > current){ height = maps.get(current + 1); } heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } public void resetHeight(int current){ this.current = current; if(maps.size() > current){ LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams(); if(layoutParams == null){ layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, maps.get(current + 1)); }else{ layoutParams.height = maps.get(current + 1); } setLayoutParams(layoutParams); } } public void calculate(int type, int height){ maps.put(type, height); } }
package cc.wxf.androiddemo; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import java.util.ArrayList; import java.util.List; import cc.wxf.androiddemo.indicator.IconPagerAdapter; /** * Created by ccwxf on 2016/6/17. */ public class ListFragmentAdapter extends FragmentPagerAdapter implements IconPagerAdapter{ private List<ListFragment> fragments = new ArrayList<ListFragment>(); private static final String[] CONTENT = new String[] { "Calendar", "Camera", "Alarms", "Location" }; public ListFragmentAdapter(WrapContentViewPager viewPager, FragmentManager fm) { super(fm); fragments.add(new ListFragment(viewPager ,1)); fragments.add(new ListFragment(viewPager, 2)); fragments.add(new ListFragment(viewPager, 3)); } @Override public Fragment getItem(int position) { return fragments.get(position); } @Override public int getIconResId(int index) { return R.drawable.selector_indicator; } @Override public CharSequence getPageTitle(int position) { return CONTENT[position % CONTENT.length].toUpperCase(); } @Override public int getCount() { return fragments.size(); } }
package cc.wxf.androiddemo; import android.annotation.SuppressLint; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import java.util.ArrayList; import java.util.List; /** * Created by ccwxf on 2016/6/17. */ public class ListFragment extends Fragment { private WrapContentViewPager viewPager; private int type; public ListFragment() { } @SuppressLint("ValidFragment") public ListFragment(WrapContentViewPager viewPager, int type) { this.viewPager = viewPager; this.type = type; } @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_item, null); WrapContentListView listView = (WrapContentListView) view.findViewById(R.id.listView); List<String> data = new ArrayList<String>(); for(int i = 0; i < type * 5; i++){ data.add("aaa"); } listView.setAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, data)); viewPager.calculate(type, listView.getRealHeight()); return view; } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <cc.wxf.androiddemo.WrapContentListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent" android:cacheColorHint="@android:color/transparent" android:divider="@android:color/darker_gray" android:dividerHeight="@dimen/divider" android:listSelector="@android:color/transparent" /> </LinearLayout>
package cc.wxf.androiddemo; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.widget.ListAdapter; import android.widget.ListView; /** * Created by ccwxf on 2016/6/17. */ public class WrapContentListView extends ListView { private int height; public WrapContentListView(Context context) { super(context); } public WrapContentListView(Context context, AttributeSet attrs) { super(context, attrs); } public WrapContentListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public void setAdapter(ListAdapter adapter) { super.setAdapter(adapter); View item = adapter.getView(0, null, null); item.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); int itemHeight = item.getMeasuredHeight(); int count = adapter.getCount(); height = itemHeight * count + getResources().getDimensionPixelSize(R.dimen.divider) * count; measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), height); } public int getRealHeight(){ return height; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); } }
Android嵌套滑动控件的冲突解决和ViewPager适配当前子控件高度不留空白的办法
标签:
原文地址:http://blog.csdn.net/cc_lova_wxf/article/details/51705928