0

I am implementing some code from Google (the SlidingTabLayout and SlidingTabStrip, found easily online) and I'm trying to use it with ViewPager to get sliding tabs in my Fragment. The thing is, I am using PagerAdapter as an extension in my main tab fragment class, which is used for my adapter to show the view of what's in the tabs. I am able to get a basic view of the tabs working in my fragment CuteCollectionFragment.java, but when I click on them, they take usually 2 clicks for the new tab to be highlighted, plus you cannot swipe to get to the new tab. My suspicion is that because the base code, which is normally meant for a main activity, must be put in a Fragment (because of my Navigation Drawer), it is conflicting with my Navigation Drawer, which is already sliding. But that's just a guess.

Basically, I must use Fragments, not activities. But how are they conflicting and how do I fix that? All examples online I found want you to use FragmentPagerAdapter instead of PagerAdapter as the extension for my adapter, but I can't do that because it requires you to use a FragmentManager that is support v.4. I can't use that in my CuteMainActivity (the one that has my nav drawer code) because then I can't click on each nav drawer menu item and go to a Fragment, I get red errors on my switch statement on the Fragment fragment part, which says my fragments must all extend FragmentActivity, but they can't with a nav drawer, they MUST extend Fragment!

Anyway, gosh this is so confusing. Mainly I just want to know 2 things:

  1. Why are my tabs not sliding (and why do they require 2 clicks)

  2. How do I hook up my inner TabsAdapter class to show my tab classes (which are all Fragments). I have my tab fragment classes/xmls all ready (e.g. PhotoTab.java, VideoTab.java, etc), but how do I hook those up to their views in the tabs?

Here is my entire project if you wanted to just run and have a look for yourself. ICollectCute app

I will only include below my Fragment that I am trying to put the slider tab code in, plus the xmls they draw from. If you need more files, let me know. The only other ones you might need (but probably not) are the Google classes called SlidingTabLayout and SlidingTabStrip or perhaps my CuteMainActivity where I put all the Navigation Drawer code. But the main place to look for additions/errors is my CuteCollectionFragment class, since the sliding tabs need to implement there.

I had help getting the code I have from this S.O. post.

Thanks for your help!

CuteCollectionFragment.java

package org.azurespot.cutecollection;

import android.app.Fragment;
import android.app.FragmentManager;
import android.os.Bundle;
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.TextView;

import org.azurespot.R;

/**
 * Created by mizu on 1/26/15.
 */
public class CuteCollectionFragment extends Fragment {

    static final String LOG_TAG = "SlidingTabsBasicFragment";
    private SlidingTabLayout mSlidingTabLayout;
    private ViewPager mViewPager;
    FragmentManager fragmentManager;

    View photoView;
    View videoView;
    View audioView;
    View textView;

    private static final int PHOTO_TAB = 0;
    private static final int VIDEO_TAB = 1;
    private static final int AUDIO_TAB = 2;
    private static final int TEXT_TAB = 3;



    public CuteCollectionFragment(){}


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_cute_collection,
                                                            container, false);

        photoView = inflater.inflate(R.layout.photo_tab,
                container, false);

        videoView = inflater.inflate(R.layout.video_tab,
                container, false);
        audioView = inflater.inflate(R.layout.audio_tab,
                container, false);
        textView = inflater.inflate(R.layout.text_tab,
                container, false);

//      Toolbar toolbar = (Toolbar) rootView.findViewById(R.id.toolbar);

        fragmentManager = getActivity().getFragmentManager();

        mViewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
        mViewPager.setAdapter(new TabsAdapter());
        mSlidingTabLayout = (SlidingTabLayout) rootView.findViewById(R.id.sliding_tabs);
        mSlidingTabLayout.setViewPager(mViewPager);


        return rootView;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

//
    }

    class TabsAdapter extends PagerAdapter {

        /**
         * @return the number of pages (tabs) to display
         */
        @Override
        public int getCount() {
            return 5;
        }

        /**
         * @return true if the value returned from
         *         {@link #instantiateItem(ViewGroup, int)} is the same object
         *         as the {@link View} added to the {@link ViewPager}.
         */
        @Override
        public boolean isViewFromObject(View view, Object o) {
            return o == view;
        }

        // BEGIN_INCLUDE (pageradapter_getpagetitle)
        /**
         * Return the title of the item at {@code position}. This is important
         * as what this method returns is what is displayed in the
         * {@link SlidingTabLayout}.
         * <p>
         * Here we construct one using the position value, but for real
         * application the title should refer to the item's contents.
         */
        @Override
        public CharSequence getPageTitle(int position) {
            return "Item " + (position + 1);

        }

        // END_INCLUDE (pageradapter_getpagetitle)

        /**
         * Instantiate the {@link View} which should be displayed at
         * {@code position}. Here we inflate a layout from the apps resources
         * and then change the text view to signify the position.
         */
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            // Inflate a new layout from our resources

            View view = getActivity().getLayoutInflater().inflate(R.layout.pager_item,
                    container, false);
            // Add the newly created View to the ViewPager
            container.addView(view);

            // Retrieve a TextView from the inflated View, and update it's text
            TextView title = (TextView) view.findViewById(R.id.item_title);
            title.setText(String.valueOf(position + 1));

//            Log.i(LOG_TAG, "instantiateItem() [position: " + position + "]");

            // Return the View
            return view;
        }

        /**
         * Destroy the item from the {@link ViewPager}. In our case this is
         * simply removing the {@link View}.
         */
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
//            Log.i(LOG_TAG, "destroyItem() [position: " + position + "]");
        }

    }

}

fragment_cute_collection.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#2198bb" >

    <!--<android.support.v7.widget.Toolbar-->
        <!--xmlns:app="http://schemas.android.com/apk/res-auto"-->
        <!--android:id="@+id/toolbar"-->
        <!--android:layout_width="match_parent"-->
        <!--android:layout_height="wrap_content"-->
        <!--android:minHeight="?attr/actionBarSize"-->
        <!--app:theme="@style/ThemeOverlay.AppCompat.ActionBar">-->

    <org.azurespot.cutecollection.SlidingTabLayout
        android:id="@+id/sliding_tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <!--</android.support.v7.widget.Toolbar>-->

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0px"
        android:background="@android:color/white" />


</RelativeLayout>

pager_item.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:gravity="center">

    <TextView
        android:id="@+id/item_subtitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Page:"/>

    <TextView
        android:id="@+id/item_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="80sp" />

</LinearLayout>

Here is one of my adapter classes. Each tab will have their own class and adapter class. This is one (although not hooked up with the CuteCollectionFragment.java yet, because I don't know how):

PhotoTab.java

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridView;

import org.azurespot.R;

/**
 * Created by mizu on 2/8/15.
 */
public class PhotoTab extends Fragment{

    private GridView gridView;
    private GridViewPhotoAdapter gvPhotoAdapter;

    public PhotoTab(){}

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View v = inflater.inflate(R.layout.photo_tab, container, false);

        // with fragments, make sure you include the rootView when finding id
        gridView = (GridView) v.findViewById(R.id.photo_grid);
        // Create the Custom Adapter Object
        gvPhotoAdapter = new GridViewPhotoAdapter(getActivity());
        // Set the Adapter to GridView
        gridView.setAdapter(gvPhotoAdapter);

        return v;
    }
}

The adapter for PhotoTab.java, GridViewPhotoAdapter.java

package org.azurespot.cutecollection;

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;

import org.azurespot.R;

/**
 * Created by mizu on 2/5/15.
 */
public class GridViewPhotoAdapter extends ArrayAdapter {

    public Context context;
    public ImageView mediaPhoto;


    public GridViewPhotoAdapter(Context context) {
        super(context, 0);
        this.context = context;

    }

    public int getCount() {
        return 24;
    }

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

        View row = convertView;

        if (row == null)
        {
            LayoutInflater inflater = ((Activity) context).getLayoutInflater();
            row = inflater.inflate(R.layout.photo_grid_row, parent, false);

            mediaPhoto = (ImageView) row.findViewById(R.id.photo_view);

            mediaPhoto.setImageResource(R.drawable.ic_collection_add);

        }

        return row;

    }

}
Community
  • 1
  • 1
Azurespot
  • 3,066
  • 3
  • 45
  • 73
  • you should attach your adapter class – Xcihnegn Feb 11 '15 at 09:29
  • Thanks @Xingchen, I have added one of the tab's classes, and the adapter for that tab. – Azurespot Feb 12 '15 at 01:16
  • why the tabs in your Fragment but not in your activity? – Xcihnegn Feb 12 '15 at 08:22
  • The main activity holds the welcome screen and the navigation drawer. So the navigation drawer insists on having fragments (it's recommended). One of the drawer items is a fragment the user visits that should have tabs that hold `GridView`s and `List`s, etc... I know it's hard to imagine (the app itself has a lot going on), but I hope that makes sense. – Azurespot Feb 13 '15 at 09:40
  • @NoniA. Did you find a solution? I have the very same problem right now... – pawelo Mar 10 '15 at 14:10
  • Hi @pawelo, I did not. I decided to switch to the Google [Creating Swipe Views with Tabs](http://developer.android.com/training/implementing-navigation/lateral.html), code from the sample and I also took out my navigation drawer item from the drawer and just put the item in a button that clicks to an activity (instead of a nav drawer item that goes to a fragment), because putting a fragment inside a fragment (the sliding pager fragment in the nav drawer fragment) was not working. I still don't have sliding tabs with the new library, but hoping to resolve that within the week. – Azurespot Mar 11 '15 at 00:16
  • Are you still working on this? I have implemented Google SlidingTabLayout project. And I believe I never got a problem in swiping between tabs. Since I have conversed with you in the past, you can ping me somehow. – The Original Android Sep 02 '15 at 06:38
  • Thanks OA! I'm not working on it, but thanks for the thought. :) – Azurespot Sep 03 '15 at 02:18

1 Answers1

0

I've also met this issue. I made it worked by using SlidingTabLayou and SlidingTabTrip from this https://github.com/google/iosched/tree/0a90bf8e6b90e9226f8c15b34eb7b1e4bf6d632e/android/src/main/java/com/google/samples/apps/iosched/ui/widget. Thanks for the Google I/O update.

pqtuan86
  • 59
  • 1
  • 3
  • Hi, welcome to StackOverflow. Please don't post links as answers, if they go offline your answer becomes useless. Instead, use the info to build your answer and use the link as reference only. Thanks. – Cthulhu Jul 27 '15 at 10:21