ViewPager within ListView row item

£可爱£侵袭症+ 提交于 2019-12-22 04:39:22

问题


I have read a lot of related questions regarding this question. However, none of them has been answered. I am trying to add a ViewPager to each row in the ListView where there are two layouts within the pager. I believe this is doable because of SwipeListView.

Now I have implemented it. However, a blank page is showing with a line in the middle. No rows are appearing.

Here is my code:

MainActivity + ArrayAdapter

public class MainActivity extends Activity {

    ListView list;
    String[] heros;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        heros = getResources().getStringArray(R.array.heros);

        list = (ListView) findViewById(R.id.listView1);
        list.setAdapter(new CustomAdapter(this, heros));
    }

    public class CustomAdapter extends ArrayAdapter<String>
    {
        String[] heros;
        Context context;
        public CustomAdapter(Context context, String[] heros) {
            super(context, R.layout.pager_item_list, R.id.listView1, heros);
            // TODO Auto-generated constructor stub
            this.heros = heros;
            this.context = context;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View row = inflater.inflate(R.layout.pager_item_list, parent, false);

            Log.d("how many times", "I really don't know how it should be");

            ViewPager pager = (ViewPager) row.findViewById(R.id.pager);
            pager.setId(position);
            pager.setAdapter(new PagerCustomAdapter());

            pager.setCurrentItem(0);

            return row;
        }
    }
}

Here is my pageAdapter

public class PagerCustomAdapter extends PagerAdapter{
    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return 2;
    }

    @Override
    public Object instantiateItem(View container, int position) {
        // TODO Auto-generated method stub

        LayoutInflater inflater = (LayoutInflater) container.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        int id = 0;

        Log.d("I am in pagerAdater", "I am here, dammit!");

        switch(position)
        {
            case 0:
                id = R.layout.fragment_top_item;
                break;
            case 1:
                id = R.layout.fragment_bottom_item;
                break;
        }
        View view = inflater.inflate(id, null);
        ((ViewPager)container).addView(view, 0);
        return view;
    }

    @Override
    public void destroyItem(View arg0, int arg1, Object arg2) {
        ((ViewPager) arg0).removeView((View) arg2);
    }

    @Override
    public boolean isViewFromObject(View arg0, Object arg1) {
        // TODO Auto-generated method stub
        return arg0 == ((View) arg1);
    }

    @Override
    public Parcelable saveState() {
        return null;
    }

}

I have tried both pagerAdapter & FragmentPagerAdapter and both had the same result

I added two log messages in getView() and instantiateItem() and both are being read in logcat as expected. There are neither warnings nor errors in LogCat.

What am I missing?

Update

XML of activity_main

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

<ListView
    android:id="@+id/listView1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true" >
</ListView>

</RelativeLayout>

XML of pager_item_list

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:orientation="vertical" >

    <android.support.v4.view.ViewPager
         android:id="@+id/pager"
         android:layout_width="match_parent"
         android:layout_height="match_parent" >
    </android.support.v4.view.ViewPager>
</LinearLayout>

回答1:


I am not sure what you're trying to achieve.. Do you want to change the view when a event happens? like when you click on it? or do you want the same result like the SwipeListView.

If you want to change the view you coult try to use a ViewFlipper anc change the layout when the event occurs. But i'm not sure if this is the result you want




回答2:


A ViewPager when used inside a ListView row needs to have a unique android:id (as in each row must have a different id). This is because the FragmentManager that is associated with the ViewPager adapter uses the id along with the position to store the fragments. This means if you just use the defaults things will get overwritten.

Below is a sample PagerAdapter that allows you to override the default makeFragmentName method.

import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Parcelable;
import android.support.v13.app.FragmentCompat;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;

public abstract class TaggedFragmentPagerAdapter extends PagerAdapter {

    private final FragmentManager mFragmentManager;

    private FragmentTransaction mCurTransaction = null;

    private Fragment mCurrentPrimaryItem = null;

    public TaggedFragmentPagerAdapter(FragmentManager fm) {
        mFragmentManager = fm;
    }

    /**
     * Return the Fragment associated with a specified position.
     */
    public abstract Fragment getItem(int position);

    public String getItemTag(int position) {
        // Maintain backward compatibility
        return String.valueOf(getItemId(position));
    }

    @Override
    public void startUpdate(ViewGroup container) {
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }

        // Do we already have this fragment?
        String name = makeFragmentName(position, container.getId(), getItemTag(position));
        Fragment fragment = mFragmentManager.findFragmentByTag(name);
        if (fragment != null) {
            // FIXME : Start fix.
            if (!fragment.isDetached()) {
                mCurTransaction.detach(fragment);
            }
            // FIXME : End fix.
            mCurTransaction.attach(fragment);
        } else {
            fragment = getItem(position);
            mCurTransaction.add(container.getId(), fragment, name);
        }
        if (fragment != mCurrentPrimaryItem) {
            FragmentCompat.setMenuVisibility(fragment, false);
            FragmentCompat.setUserVisibleHint(fragment, false);
        }

        return fragment;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }
        mCurTransaction.detach((Fragment) object);
    }

    @Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
        Fragment fragment = (Fragment) object;
        if (fragment != mCurrentPrimaryItem) {
            if (mCurrentPrimaryItem != null) {
                FragmentCompat.setMenuVisibility(mCurrentPrimaryItem, false);
                FragmentCompat.setUserVisibleHint(mCurrentPrimaryItem, false);
            }
            if (fragment != null) {
                FragmentCompat.setMenuVisibility(fragment, true);
                FragmentCompat.setUserVisibleHint(fragment, true);
            }
            mCurrentPrimaryItem = fragment;
        }
    }

    @Override
    public void finishUpdate(ViewGroup container) {
        if (mCurTransaction != null) {
            mCurTransaction.commitAllowingStateLoss();
            mCurTransaction = null;
            mFragmentManager.executePendingTransactions();
        }
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return ((Fragment) object).getView() == view;
    }

    @Override
    public Parcelable saveState() {
        return null;
    }

    @Override
    public void restoreState(Parcelable state, ClassLoader loader) {
    }

    /**
     * Return a unique identifier for the item at the given position.
     *
     * <p> The default implementation returns the given position. Subclasses should override this method if the positions of items
     * can change. </p>
     *
     * @param position Position within this adapter
     * @return Unique identifier for the item at position
     */
    public long getItemId(int position) {
        return position;
    }

    protected String makeFragmentName(int position, int viewId, String tagName) {
        return "android:switcher:" + viewId + ":" + tagName;
    }
}



回答3:


I faced a similar issue, and what I did is I explicity set the height of the viewPager and its parent. This worked for me.

<?xml version="1.0" encoding="utf-8"?>
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="200dip"
    android:orientation="vertical" >

   <android.support.v4.view.ViewPager
      android:id="@+id/pager"
      android:layout_width="match_parent"
      android:layout_height="200dip" >
   </android.support.v4.view.ViewPager>
 </LinearLayout>

I don't know if there is a better solution, but if you do get a better solution please comment!



来源:https://stackoverflow.com/questions/20774098/viewpager-within-listview-row-item

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!