maciejkiner
maciejkiner

Reputation: 31

Android gallery in ListView row

I'm trying to achieve the effect such as Airbnb app for Android, list where in each rows is scrolled horizontally gallery (and each row have top layer with title an so). I'm using a ListView with FrameLayout and ViewPager in each cell, but I get a NullPointerException when scrolling. Fragments with pictures lose the pointer to the parent fragment (I found there is some bug in Android Support Library, I spent a few days searching for solution).

For now I do not want to show the code. I just would like to know is Viewpager in the ListView is a good idea, or maybe I have to do it in another way. Maybe there is a library for the implementation of such behavior?

Upvotes: 2

Views: 1351

Answers (1)

maciejkiner
maciejkiner

Reputation: 31

I found a solution on this page http://dorkus.hatenablog.com/entry/2014/01/16/021853. Needs some optimalizations, but imho it's a good base for future work.

Edit

View in action

List Item Layout

Item in List

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="match_parent"
    android:orientation="vertical" >

    <ListView
    android:id="@+id/listView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    </ListView>

</LinearLayout>

row.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="match_parent"
    android:orientation="vertical" >

<android.support.v4.view.ViewPager
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:layout_gravity="center" />

</LinearLayout>

page1.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="match_parent"
    android:background="#ffffff"
    android:orientation="vertical" >

    <TextView
    android:id="@+id/text"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:textColor="#000000"
    android:singleLine="true"
    android:textSize="20sp" />

</LinearLayout>

page2.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="match_parent"
    android:orientation="horizontal" >

    <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:background="#00000000" >

    </RelativeLayout>

    <Button
    android:id="@+id/button2"
    android:layout_width="70dp"
    android:layout_height="match_parent"
    android:background="#cc2828"
    android:text="削除"
    android:textColor="#ffffff" />

</LinearLayout>

MyListAdapter.java

public class MyListAdapter extends ArrayAdapter<String>{

    private LayoutInflater inflater = null;
    private static final float BUTTON_WIDTH_DP = 70f;
    private int margin;

    public MyListAdapter(Context context, int resource,String[] items) {
        super(context, resource,items);
        inflater = LayoutInflater.from(context);

        //ページ2のRelativeLayoutの幅を計算してmarginへ格納する。
        float density = getContext().getResources().getDisplayMetrics().density; 
        int buttonWidthPX = (int) (BUTTON_WIDTH_DP * density + 0.5f);

        WindowManager wm = (WindowManager)getContext().getSystemService(getContext().WINDOW_SERVICE);
    Display dp = wm.getDefaultDisplay();
        margin = dp.getWidth() - buttonWidthPX;

    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if(convertView == null){
            convertView = inflater.inflate(R.layout.row,null);
        }

        ViewPager viewPager = (ViewPager)convertView.findViewById(R.id.viewpager);
        viewPager.setPageMargin(-margin);
        MyPagerAdapter adapter = new MyPagerAdapter(getContext(),getItem(position));
        viewPager.setAdapter(adapter);

        return convertView;
    }
}

MyPagerAdapter.java

public class MyPagerAdapter extends PagerAdapter{

    private LayoutInflater inflater;

    private static final int PAGE_NUM = 2;
    private String str;

    public MyPagerAdapter(Context context,String str) {
        super();
        inflater = LayoutInflater.from(context);
        this.str = str;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {

        LinearLayout layout = null;
        if(position == 0){
            layout = (LinearLayout)inflater.inflate(R.layout.page1, null);
            TextView text = (TextView)layout.findViewById(R.id.text);
            text.setText(str);
        }else{
            layout = (LinearLayout)inflater.inflate(R.layout.page2, null);
        }

        container.addView(layout);

        return layout;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        ((ViewPager) container).removeView((View) object);
    }

    @Override
    public int getCount() {

        return PAGE_NUM;
    }

    @Override
    public boolean isViewFromObject(View view, Object obj) {

        return view.equals(obj);
    }

}

MainActivity.java

public class MainActivity extends Activity {

    private String str[] = {"項目1","項目2","項目3","項目4","項目5","項目6","項目7","項目8","項目9","項目10"};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        ListView listView = (ListView)findViewById(R.id.listView);
        MyListAdapter adapter = new MyListAdapter(this,R.layout.row,str);
        listView.setAdapter(adapter);
    }
}

Upvotes: 1

Related Questions