4

I'm trying to make a TableLayout within a Fragment that supports column swiping.

As the image in the link below shows, the first column ("Header 1") should be fixed, whereas the other columns ("Header 2", "Header 3", and "Header 4" ) should be swipeable.

Depending on which column it is, the header should also show one or two arow icons. On clicking these arrow icons, the columns should also change.

Any ideas how to best implement this? Thanks in advance.

Show image

user3165984
  • 121
  • 2
  • 10
  • Actually I didn't get your requirement! I hope you know the functionality of `ViewPager`. (If not please go through that once) Later check whether that satisfies. Because what you asking exactly like `ViewPager`, so you don't need `TableLayout`. To display those data list you can use `ListView`, `LinearLayout` (with vertical orientation) or even you can even use `TableLayout` with single column! If this is not your requirement then please explain bit more about your requirement! – Kavin Prabhu Aug 22 '15 at 13:49

3 Answers3

4

First of all, thanks to everyone. Seems like i didn't see the obvious.

The solution for me was to use a fixed ListView for the first column and a ViewPager with a ListView for the slideable columns.

In my main layout file, I have therefore declared a ListView and a ViewPager with layout weights set to 0.5 on both of them. This makes sure that both the fixed column and the slideable column have the same width:

my_main_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:padding="16dp">

<LinearLayout
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="0.5"
    android:orientation="vertical">

    <TextView
        android:id="@+id/firstColumnHeader"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:paddingRight="@dimen/padding_horizontal_small"
        android:textAppearance="?android:textAppearanceMedium"
        android:textStyle="bold" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@color/gray" />


    <ListView
        android:id="@+id/firstColumnList"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:divider="@null"
        android:dividerHeight="0dp"
        android:scrollbars="none"
        />
</LinearLayout>


<android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:listSelector="@android:color/transparent"
    android:layout_weight="0.5" />

For the slideable column, I made a second custom layout file with the ListView and with a horizontal LinearLayout containing the column name and the two arrows:

slideable_column_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<LinearLayout
    android:id="@+id/viewpagerHeader"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/leftPagerArrow"
        android:layout_width="wrap_content"
        android:layout_height="15dp"
        android:layout_gravity="center_vertical"
        android:layout_marginRight="10dp"
        android:adjustViewBounds="true"
        android:src="@drawable/arrow_left" />

    <TextView
        android:id="@+id/headerText"
        android:textAppearance="?android:textAppearanceMedium"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textStyle="bold" />

    <ImageView
        android:id="@+id/rightPagerArrow"
        android:layout_width="wrap_content"
        android:layout_height="15dp"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp"
        android:adjustViewBounds="true"
        android:src="@drawable/arrow_right" />

</LinearLayout>

<View
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="@color/gray" />

<ListView
    android:id="@android:id/list"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:divider="@null"
    android:dividerHeight="0dp"
    android:listSelector="@android:color/transparent"
    android:scrollbars="none" />

Then, in my Fragment where I want to use the slideable columns, I implemented the ViewPager, a PagerAdapter and the ListViews:

import android.app.Fragment;
import android.app.FragmentManager;
import android.app.ListFragment;
import android.os.Bundle;
import android.support.v13.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;


public class MyFragment extends Fragment {

    private static final int NUM_PAGES = 4;
    private static final String[] titles = {"Column2", "Column3", "Column4", "Column5"};
    private final String[] column_one = {"Data 1.0", "Data 1.1", "Data 1.2", "Data 1.3"};

    public static final String[] column_two = {"Data 2.0", "Data 2.1", "Data 2.2", "Data 2.3"};

    public static final String[] column_three = {"Data 3.0", "Data 3.1", "Data 3.2", "Data 3.3"};

    public static final String[] column_four = {"Data 4.0", "Data 4.1", "Data 4.2", "Data 4.3"};

    public static final String[] column_five = {"Data 5.0", "Data 5.1", "Data 5.2", "Data 5.3"};


    public static ViewPager mViewPager;
    private PagerAdapter mAdapter;
    private ListView mListView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.my_main_layout,
                container, false);

        //Set ListView and its adapter
        mListView = (ListView) view.findViewById(R.id.firstColumnList);
        ArrayAdapter<String> sAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, column_one);
        mListView.setAdapter(sAdapter);

        //Set ViewPager and its adapter
        mViewPager = (ViewPager) view.findViewById(R.id.pager);
        mAdapter = new ViewPagerAdapter(getFragmentManager());
        mViewPager.setAdapter(mAdapter);

        return view;
    }

    public static class ViewPagerAdapter extends FragmentStatePagerAdapter {
        public ViewPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public int getCount() {
            return NUM_PAGES;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return titles[position];
        }

        @Override
        public Fragment getItem(int position) {
            return SlidingListFragment.newInstance(position);
        }


    }

    public static class SlidingListFragment extends ListFragment {

        private int mNum;
        private ImageView leftArrow;
        private ImageView rightArrow;

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            if (getArguments() != null) {
                mNum = getArguments().getInt("num");

            } else {
                mNum = 1;
            }
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.sliding_column_layout,
                    container, false);

            ListView slidingList = (ListView) view.findViewById(android.R.id.list);
            TextView header = (TextView) view.findViewById(R.id.headerText);
            header.setText(getHeader());
            leftArrow = (ImageView) view.findViewById(R.id.leftPagerArrow);
            rightArrow = (ImageView) view.findViewById(R.id.rightPagerArrow);
            if (leftArrow.getVisibility() == View.VISIBLE) {
                leftArrow.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mViewPager.setCurrentItem(mNum - 1);
                    }
                });
            }
            if (rightArrow.getVisibility() == View.VISIBLE) {
                rightArrow.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mViewPager.setCurrentItem(mNum + 1);
                    }
                });
            }
            setArrows();

            slidingList.setAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, getMyListArray()));

            return view;
        }

        private String getHeader() {
            String header = "";
            switch (mNum) {
                case 0:
                    header = titles[0];
                    break;
                case 1:
                    header = titles[1];
                    break;
                case 2:
                    header = titles[2];
                    break;
                case 3:
                    header = titles[3];
                    break;
            }
            return header;
        }

        private void setArrows() {
            switch (mNum) {
                case 0:
                    leftArrow.setVisibility(View.INVISIBLE);
                    break;
                case 1:
                    break;
                case 2:
                    break;
                case 3:
                    rightArrow.setVisibility(View.INVISIBLE);
                    break;
            }
        }

        private String[] getMyListArray() {
            String[] returnArray = {"no lists"};
            switch (mNum) {
                case 0:
                    returnArray = column_two;
                    break;
                case 1:
                    returnArray = column_three;
                    break;
                case 2:
                    returnArray = column_four;
                    break;
                case 3:
                    returnArray = column_five;
                    break;
            }
            return returnArray;
        }


        /**
         * Create a new instance of SlidingFragment, providing "num"
         * as an argument.
         */
        static SlidingListFragment newInstance(int num) {
            SlidingListFragment f = new SlidingListFragment();

            // Supply num input as an argument.
            Bundle args = new Bundle();
            args.putInt("num", num);
            f.setArguments(args);

            return f;
        }

    }

}

I don't know whether this is the most efficient solution, but it is working :-)

user3165984
  • 121
  • 2
  • 10
0

Check out ViewPager and PagerAdapter

http://developer.android.com/training/animation/screen-slide.html

Sam Edwards
  • 874
  • 8
  • 19
  • Thanks, I know the link but I don't know how to combine the Viewpager with the TableLayout – user3165984 Aug 22 '15 at 13:41
  • They are different. You can have a TableLayout inside of one of the Pages, but a table layout if just for showing items on one screen typically. TableLayout doesn't provide the swiping features you are looking for. Instead, consider each "Page" of the "ViewPager" to be a column of the table. It works out very similarly. – Sam Edwards Aug 22 '15 at 13:52
0

Check ViewPager for sliding fragments. Here is tutorial.

Insert this as child of TableRow of your TableLayout :

<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Malwinder Singh
  • 6,644
  • 14
  • 65
  • 103