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>
Our viewpager isn’t in the android.widget package hence we qualify with the full class name of the element. Shall get replaced by our fragments layouts. (b). Model Layout The model for a single row item in our custom listview.
Steps for implementing viewpager: Adding the ViewPager widget to the XML layout (usually the main_layout). Creating an Adapter by extending the FragmentPagerAdapter or FragmentStatePagerAdapter class. An adapter populates the pages inside the Viewpager.
Android ListView is a ViewGroup which is used to display the list of items in multiple rows and contains an adapter which automatically inserts the items into the list. The main purpose of the adapter is to fetch data from an array or database and insert each item that placed into the list for the desired result.
The data inside our ListView will be saved in SQLite database. SQLite is a local file-based database written in C programming language and normally comes packaged already with android framework. Of course before retrieving data from the SQLite database we will first need to insert that data in the first place.
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
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With