将 ViewPager 作为一行放置在 ListView 中
Posted
技术标签:
【中文标题】将 ViewPager 作为一行放置在 ListView 中【英文标题】:Placing ViewPager as a row in ListView 【发布时间】:2013-02-01 22:45:49 【问题描述】:我尝试将 ViewPager 用作 ListView 中的一行,但得到一个奇怪的行为 - 只有第一行有效,但当我滚动列表时它消失了。当我滚动一个空行时,突然正在查看上面的行。 似乎 android 创建了一个寻呼机并将其用于所有行。
这是我在启动应用程序时看到的:
这是我的行布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:background="@android:color/white"
android:orientation="vertical"
android:paddingBottom="2dp" >
<TextView
android:id="@+id/textViewFriendName"
style="@style/TextStyle"
android:layout_
android:layout_
android:background="@color/myFriendsBg"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:text="TextView" />
<View style="@style/DividerHorizontalStyle_gray" />
<android.support.v4.view.ViewPager
android:id="@+id/pagerMyFriendHabits"
android:layout_
android:layout_ />
<View style="@style/DividerHorizontalStyle" />
</LinearLayout>
这是我的列表适配器:
public class MyFriendsAdapter extends BaseAdapter implements OnClickListener
private ArrayList<UiD_UserFriend> mItems;
private Context mContext;
private FragmentManager mFragmentManager;
public MyFriendsAdapter(Context context, ArrayList<UiD_UserFriend> items, FragmentManager fragmentManager)
mContext = context;
mItems = items;
mFragmentManager = fragmentManager;
@Override
public int getCount()
return mItems.size();
@Override
public Object getItem(int position)
return mItems.get(position);
@Override
public long getItemId(int position)
return position;
@Override
public View getView(int position, View currentView, ViewGroup viewGroup)
Holder holder = null;
if (currentView == null)
currentView = View.inflate(mContext, R.layout.view_list_item_myfriends, null);
holder = new Holder();
holder.textViewUserName = (TextView) currentView.findViewById(R.id.textViewFriendName);
holder.mMyFriendspager = (ViewPager) currentView.findViewById(R.id.pagerMyFriendHabits);
currentView.setTag(holder);
else
holder = (Holder) currentView.getTag();
holder.textViewUserName.setText(mItems.get(position).getmName());
MyFriendPagerAdapter tempMyFriendPagerAdapter = new MyFriendPagerAdapter(mFragmentManager, mItems.get(position).getFriendHabits());
holder.mMyFriendspager.setAdapter(tempMyFriendPagerAdapter);
return currentView;
class Holder
TextView textViewUserName;
ViewPager mMyFriendspager;
这是我的寻呼机适配器:
public class MyFriendPagerAdapter extends FragmentPagerAdapter
private ArrayList<UiD_Habit> mHabits;
public MyFriendPagerAdapter(FragmentManager fm, ArrayList<UiD_Habit> habits)
super(fm);
mHabits = habits;
@Override
public Fragment getItem(int index)
return new FragmentMyFriendPage(mHabits.get(index));
@Override
public int getCount()
return mHabits.size();
【问题讨论】:
你能分享一下这个实现的完整代码吗?谢谢 你是如何解决问题的,我在回收站视图中遇到了同样的问题 【参考方案1】:当您需要动态添加寻呼机时,您需要使用ViewPager.setId()
为每个寻呼机设置一个ID。
【讨论】:
强制唯一 ID 的一个好方法是在 xml 文件中将它们声明为整数或其他资源,然后用 Java 中的提供程序包装它们。 Liren Peretz:viewPager 的 setId() 在哪里?我正在做同样的事情并遇到同样的问题。 在您创建寻呼机的地方,问题是您创建了一个动态视图寻呼机并且它们没有 id。 在 getView for viewpager 中为每一行设置标签效果很好。 @Pinhassi:我已经尝试了上面的代码,但我得到了“android.content.res.Resources$NotFoundException”。你能分享一下你是如何解决这个问题的吗?【参考方案2】:我创建了示例应用
带有片段的示例 ViewPager:https://dl.dropboxusercontent.com/u/20178650/builds/listviewwithviewpager.zip
但是有一个很大的缺点。所有的单元格都存储在内存中,应用程序可能会因内存不足而崩溃,无论您是否有很多单元格
编辑:
根据经验,它已经找到了。如果在 ViewPager 中使用简单的视图而不是片段。我可以正确写一个适配器,而且不会被内存打动
带有视图的示例 ViewPager:https://dl.dropboxusercontent.com/u/20178650/builds/listviewwithviewpager_v2.zip
希望有人能帮忙
【讨论】:
很棒的例子thanx..你也可以在这里帮忙吗? ***.com/questions/27200546/… 谢谢!它有很大帮助!我投票支持你所有的答案。【参考方案3】: /// <summary>
/// To Improve ListView Memory Optimization
/// </summary>
public class ViewPageHolder : Java.Lang.Object
public TextView _firstTextView get; set;
public ViewPager _ViewPager get; set;
public CirclePageIndicator _CirclePageIndicator get; set;
Queue<int> _pagerId= new Queue<int>(Enumerable.Range(10, 100));//To set a Unique Id to View Pager to avoid ListView Recycle memory issue
public override View GetView(int position, Android.Views.View convertView, Android.Views.ViewGroup parent)
View view = convertView;
ViewPageHolder ViewPageHolder = null;
if (view != null)
ViewPageHolder = view.Tag as ViewPageHolder ;
if (ViewPageHolder == null)
ViewPageHolder = new ViewPageHolder ();
view = Context.LayoutInflater.Inflate(Resource.Layout.SystemListLayout, null);
ViewPageHolder .SystemNameTextView = view.FindViewById<TextView>(Resource.Id.SystemNameTextView);
//View Pager
ViewPageHolder._ViewPager = view.FindViewById<ViewPager>(Resource.Id.viewPager);
//Circle Pager Indicator
ViewPageHolder.CirclePageIndicator = view.FindViewById<CirclePageIndicator>(Resource.Id.viewPageIndicator);
ViewPageHolder._ViewPager.Id = _pagerId.Dequeue();
ViewPageHolder._ViewPager.Adapter = new ZoneRenameViewPagerFragmentAdapter(fm, Context, List.ElementAt(position).Zones.ToList(), ((BaseActivity)Context).IsTablet);
ViewPageHolder.CirclePageIndicator.SetViewPager(ZoneRenameHolder.ZoneRenameViewPager);
view.Tag = ZoneRenameHolder;
return view;
-
使用支架
使用标签
生成唯一 ID
【讨论】:
【参考方案4】:我遇到了完全相同的问题。 解决方案:
-
使用支架
使用标签
生成唯一 ID
我解决了这个问题。 如果有人需要代码请ping我。
【讨论】:
你能用一些示例代码指导一下这是如何解决的吗? 添加了源代码。 Dory 和 Dr. aNdRO 请参考答案。以上是关于将 ViewPager 作为一行放置在 ListView 中的主要内容,如果未能解决你的问题,请参考以下文章
Android使用片段在viewpager中的页面滚动上放置动画
ViewPager2 selectCurrentItem - 选择选项卡,但在此选项卡内放置错误的片段
如何将 viewPager 作为标题添加到 ListView