Ich versuche, mehrere ViewPagers
in eine ScrollView
aufzublasen, wobei jede ViewPager
einen FragmentStatePagerAdapter verwendet.Lazy loading ViewPagers in einer ScrollView
Die ViewPager
bestehen aus Fragmenten mit drei ImageViews
für jede Seite.
Ich benutze UniversalImageLoader für das asynchrone Laden der Bilder, aber ich kann nicht eine faule Last zu arbeiten.
Das Problem ist, wenn meine app aufblähenden sagen 10 ViewPagers
mit 3 ImageViews
für jede TripplePosterFragment1
, und weitere 10 ViewPagers
mit 3 ImageViews
für TripplePosterFragment2
seit den mPager.setOffscreenPageLimit(1)
Tritte in.
Seine insgesamt 60 Asynchron-Anfragen Brennen lässt während meiner progressLayout
ist sichtbar.
Mein MainFragment
mit folgenden Methode:
private void renderSubCarousels(ArrayList<Carousel> carousels) {
LayoutInflater mInflater = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
int i = 1;
LinearLayout subCarouselLayout = (LinearLayout) mScrollView.findViewById(R.id.index_subcategory_carousel_container);
for (final Carousel carousel : carousels) {
RelativeLayout carouselWrapper = (RelativeLayout) mInflater.inflate(R.layout.main_pager_layout, null);
LinearLayout mContainer = (LinearLayout) carouselWrapper.findViewById(R.id.main_pager_container);
mContainer.setId(Constants.BASEID_LINEARLAYOUT + i);
ViewPager mPager = (ViewPager) mContainer.findViewById(R.id.main_pager);
mPager.setId(Constants.BASEID_VIEWPAGER + i);
mPager.setAdapter(new PagerPosterAdapter(getFragmentManager(),Constants.TRIPLE_POSTERS, carousel));
subCarouselLayout.addView(carouselWrapper);
i++;
}
progressLayout.setVisibility(View.GONE);
}
Mein FragmentStatePagerAdapter
:
public class PagerPosterAdapter extends FragmentStatePagerAdapter {
private int mPageSize;
private Carousel mCarousel;
public PagerPosterAdapter(FragmentManager fm, int pageSize, Carousel carousel) {
super(fm);
this.mPageSize = pageSize;
this.mCarousel = carousel;
}
@Override
public int getCount() {
int maxPageIndex = (int) Math.ceil((float) mCarousel.getAssets().size()/mPageSize);
return maxPageIndex;
}
@Override
public Fragment getItem(int position) {
ArrayList<Asset> assets = mCarousel.getAssets();
int from = position*mPageSize;
int to = (position+1)*(mPageSize);
if(to > assets.size()-1)
to = assets.size();
return (TripplePosterFragment.newInstance(assets.subList(from, to)));
}
}
Die TripplePosterFragment
wo das Image Rendering passiert:
private void initViews() {
ImageView mFirstImageView = (ImageView) mLinearLayout.findViewById(R.id.first_pager_poster);
ImageView mSecondImageView = (ImageView)mLinearLayout.findViewById(R.id.second_pager_poster);
ImageView mThirdImageView = (ImageView)mLinearLayout.findViewById(R.id.third_pager_poster);
for(int i = 0;i < assets.size(); i++){
ImageView image = null;
switch(i){
case 0:
image = (ImageView) mLinearLayout.findViewById(R.id.first_pager_poster);
break;
case 1:
image = (ImageView) mLinearLayout.findViewById(R.id.second_pager_poster);
break;
case 2:
image = (ImageView) mLinearLayout.findViewById(R.id.third_pager_poster);
break;
default:
continue;
}
//The ScrollView in MainFragment
CustomScrollView mParentScrollView = (CustomScrollView)getActivity().findViewById(R.id.index_scrollviewparent);
Rect scrollBounds = new Rect();
mParentScrollView.getHitRect(scrollBounds);
if (image.getLocalVisibleRect(scrollBounds)) {
// Any portion of the imageView, even a single pixel, is within the visible window
ImageLoader.getInstance().displayImage(assets.get(i).getPoster(), image);
System.out.println("Im within");
else {
// NONE of the imageView is within the visible window
System.out.println("Im NOT within");
}
}
}
ich überprüfen müssen, wenn die Bilder sichtbar und laden Sie sie, wenn sie sind. Aber System.out.println("Im NOT within");
ist in der Log
gespammt. Ich bin mir sicher, dass es einen ähnlichen Weg gibt, aber ich brauche Hilfe.
Ich habe versucht, eine schnelle Annäherung in einem Listview viel von dem Fleisch zu tun, aber es ist nicht optimal, zumindest nach einigen Lesen, ViewPager inside ListView
UPDATE
Samt Kernfrage nach wie vor, aber Verwenden eines neuen Ansatzes HorizontalListViews instad von Pagern.
ListViews
scheint wie der Weg zu gehen. Wenn Sie ArrayAdapter
verwenden, um eine reguläre vertikale ListView
mit mehreren zu füllen, lädt die Lazy die Bilder vertikal für jede neue Zeile und horizontal für jedes Bild innerhalb, wie vorgesehen.
Problem: Horizontale Positionen sind verloren. Die horizontalAdapter
wird von einer wiederverwerteten Ansicht auf den nächsten Listeneintrag vererbt. Diese Positionen das neue Listenelement, wo die wiederverwertete Liste Element war.
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
View view = convertView;
if (view == null) {
holder = new ViewHolder();
view = mInflater.inflate(R.layout.carousel_frame_layout, null);
holder.carouselList = (HListView) view.findViewById(R.id.hListView);
view.setTag(holder);
}
else {
holder = (ViewHolder) view.getTag();
}
Carousel mCarousel = mData.get(position);
// Problem: Re-uses adapters from convertview
if (holder.carouselList.getAdapter() == null) {
SubCategoryCarouselAdapter horizontalAdapter = new SubCategoryCarouselAdapter(mContext, mCarousel.getAssets());
holder.carouselList.setAdapter(horizontalAdapter);
} else {
((SubCategoryCarouselAdapter) holder.carouselList.getAdapter()).update(mCarousel.getAssets());
}
return view;
}
Die Lösung könnte die inneren horizontalAdapter
zu einer bestimmten Listenposition Position zu speichern sein, aber ich weiß nicht, wie dies zu tun ist, wenn die HListView
selbst zurückgeführt wird.
UPDATE 3
eine funktionierende Lösung für HListViews
gefunden. Aber ich muss noch testen, ob das für ViewPagers
funktioniert.
Seine Lazy laden Bilder sowohl horizontal als auch vertikal bei Verwendung addHeaderView
auf Eltern ListView
für jeden inneren HListView
. Ich habe HorizontalVariableListView zusammen mit UniversalImageLoader für die Karussells verwendet.
LayoutInflater mInflater = (LayoutInflater) getActivity().getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
for (final Carousel carousel : carousels) {
View carouselWrapper = mInflater.inflate(R.layout.carousel_sub_category_layout, null);
listView.addHeaderView(carouselWrapper);
listView.setAdapter(null);
HListView horizontalList = (HListView) carouselWrapper.findViewById(R.id.hListView);
SubCategoryCarouselAdapter mAdapter = new SubCategoryCarouselAdapter(getActivity(), carousel.getAssets());
horizontalList.setAdapter(mAdapter);
}
Ja, es scheint so zu sein. Ich kann das Recycling von View und Adaptern nicht zum Laufen bringen. Ich habe weg von Pagern bewegt und stattdessen HorizontalListViews verwendet. Es hat jedoch das gleiche Verhalten, wenn alle Bilder in einer ScrollView geladen werden. Wie Sie bereits gesagt haben, werden die HorizontalListViews wiederverwendet, aber auch die Adapter, die an jede wiederverwendbare Ansicht gebunden sind. Meine Antwort wurde aktualisiert! – Rob
Ich kann zwei folgende Lösungen vorschlagen: 1) speichern Sie Ihre Adapter in der Liste und erhalten Sie den benötigten Adapter durch seine Position (eigentlich glaube ich nicht, dass es eine gute Idee ist, da es in Bezug auf Speicher nicht wirksam ist) 2) add ein Zeiger auf Ihr Karussell (ich nehme an, es hat die Liste der Daten angezeigt werden) Klasse, die auf die aktive Position zeigen und dann SubCategoryCarouselAdapter Konstruktor ändern, um diesen Zeiger zu bekommen und die entsprechende Position (ich denke, dass dieser Weg ist Weg besser als die erste, wie für den Zeiger kann es nur ein int Wert sein, der die Nummer der Seite anzeigt) – Chaosit
Zumindest sollte dies funktionieren, falls Ihre HListView paginiert wird wie der ViewPager – Chaosit