Mauro Alvarez
Mauro Alvarez

Reputation: 612

Listview inside PagerTabStrip not scrolling

We're developing an app for our final project at college. We're using PagerTabStrip (ViewPager) with three tabs. Each tab contains a fragment and inside each fragment there are some View components plus a listview.

The main problem is that the listview is not scrolling while there are more items to be seen.(For example, if we have more than 10 items we cannot access the items at the bottom) Note that we can edit and delete items from the listviews(we implemented that with a longclicklistener) but scrolling functionality is the only thing that is not working. It seems that the scrolling is not enabled.

We've searched high and low but we couldn't find a solution yet.

I posted the code below.

Main activity

public class MainActivity extends AppCompatActivity implements OnPlaceSelectedListener {

/**
 * The {@link android.support.v4.view.PagerAdapter} that will provide
 * fragments for each of the sections. We use a
 * {@link FragmentPagerAdapter} derivative, which will keep every
 * loaded fragment in memory. If this becomes too memory intensive, it
 * may be best to switch to a
 * {@link android.support.v4.app.FragmentStatePagerAdapter}.
 */
private SectionsPagerAdapter mSectionsPagerAdapter;

/**
 * The {@link ViewPager} that will host the section contents.
 */
private ViewPager mViewPager;

//fragments

private TalkNowFragment talkNowFragment;
private PhraseAdmin phraseAdmin;
private PlacesCategoriesAdmin placesCategory;
private DatabaseAdapter dbAdapter;
private List<String> frases_categoria;
private MainActivity context;
private GPSTracker tracker;
private Menu menu;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    context = MainActivity.this;
    this.tracker = new GPSTracker(this.context);
    setContentView(R.layout.activity_main);
    // Create the adapter that will return a fragment for each of the three
    // primary sections of the activity.
    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
    // Set up the ViewPager with the sections adapter.
    mViewPager = (ViewPager) findViewById(R.id.container);
    mViewPager.setAdapter(mSectionsPagerAdapter);
    dbAdapter = new DatabaseAdapter(this);
    frases_categoria = new ArrayList<>();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    this.menu = menu;
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    switch (id) {
        case R.id.action_settings:
            return true;
    }
    return super.onOptionsItemSelected(item);
}

@Override
public void onPlaceSelected(Category category) {
    //we pass the fragment the data now.
    //setea el modo
    talkNowFragment.setMode(category.getName());
    //traigo las frases
    try {
       frases_categoria = dbAdapter.getPhrasesFromCategory(category.getId());
    } catch (SQLException e) {
        e.printStackTrace();
    }
    if(frases_categoria.size() > 0) {
        //set the phrases and category to the fragment
        // then it displays it on the dialog
        talkNowFragment.populatePhrases(frases_categoria,category.getName());

    }else{

    }



}

/**
 * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
 * one of the sections/tabs/pages.
 */
public class SectionsPagerAdapter extends FragmentPagerAdapter {

    final int PAGE_COUNT = 3;
    // Tab Titles
    private String tabtitles[] = new String[] { "Hablar ahora", "Lugares", "Categorías" };

    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        // getItem is called to instantiate the fragment for the given page.
        // Return a PlaceholderFragment (defined as a static inner class below).
        switch (position){
            case 0:
                talkNowFragment = TalkNowFragment.newInstance(0,"HABLAR AHORA #1");
                return talkNowFragment;
            case 1:
                placesCategory = PlacesCategoriesAdmin.newInstance(0, "LUGARES Y CATEGORIAS #2");
                return placesCategory;
            case 2:
                phraseAdmin = PhraseAdmin.newInstance(0,"FRASES #3");
                return phraseAdmin;
            default:
                return null;
        }
    }

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

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


}

/**
 * A placeholder fragment containing a simple view.
 */
public static class PlaceholderFragment extends Fragment {
    /**
     * The fragment argument representing the section number for this
     * fragment.
     */
    private static final String ARG_SECTION_NUMBER = "section_number";

    /**
     * Returns a new instance of this fragment for the given section
     * number.
     */
    public static PlaceholderFragment newInstance(int sectionNumber) {
        PlaceholderFragment fragment = new PlaceholderFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_SECTION_NUMBER, sectionNumber);
        fragment.setArguments(args);
        return fragment;
    }

    public PlaceholderFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
        TextView textView = (TextView) rootView.findViewById(R.id.section_label);
        textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
        return rootView;
    }
}
 }

Fragment PlacesCategoriesAdmin

public class PlacesCategoriesAdmin extends Fragment implements PlacesListAsyncResponse {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "page";
private static final String ARG_PARAM2 = "title";

private static final String API_KEY = "AIzaSyBCT48NGa9b5DKnvywEPSTfyGDa-BZ4Udo";

private ArrayList<String> adapterPlaces;

private GooglePlacesRequest googlePlacesRequest;
// TODO: Rename and change types of parameters
private int page;
private String title;



private ListView categoryPlaceListview;
private PlacesList placesList;
private GPSTracker tracker;
private Button search_button;
private EditText editTextSearch;
private TextView result_count;
private Button gps_buttton;
private DatabaseAdapter dbAdapter;
private FragmentActivity context;

public PlacesCategoriesAdmin() {
    // Required empty public constructor
}

/**
 * Use this factory method to create a new instance of
 * this fragment using the provided parameters.
 *
 * @param page Parameter 1.
 * @param title Parameter 2.
 * @return A new instance of fragment PlacesCategoriesAdmin.
 */
// TODO: Rename and change types and number of parameters
public static PlacesCategoriesAdmin newInstance(int page, String title) {
    PlacesCategoriesAdmin fragment = new PlacesCategoriesAdmin();
    Bundle args = new Bundle();
    args.putInt(ARG_PARAM1, page);
    args.putString(ARG_PARAM2, title);
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        page = getArguments().getInt(ARG_PARAM1);
        title = getArguments().getString(ARG_PARAM2);
    }

    //init placesList
    placesList = new PlacesList();
    //instancia el gps.
    tracker = new GPSTracker(getActivity());
    dbAdapter = new DatabaseAdapter(getContext());
    context = this.getActivity();

}
private void setNameGPSButton(){
    if (!tracker.isGPSEnabled()) {
        gps_buttton.setText(getResources().getString(R.string.activate_GPS));
    } else {
        gps_buttton.setText(getResources().getString(R.string.deactivate_GPS));
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View viewRoot =  inflater.inflate(R.layout.fragment_places_categories_admin, container, false);
    search_button = (Button)viewRoot.findViewById(R.id.search_place_gps);
    editTextSearch = (EditText)viewRoot.findViewById(R.id.searchFieldCatPlace);
    categoryPlaceListview = (ListView)viewRoot.findViewById(R.id.listview_category_place);
    result_count = (TextView)viewRoot.findViewById(R.id.result_count_text);
    gps_buttton = (Button)viewRoot.findViewById(R.id.buttonGPS);

    this.setNameGPSButton();
    gps_buttton.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
               startActivityForResult(intent, 0);
                onActivityResult(0, 0, intent);

               System.out.println("sigue ejecución, no deveria imprimirse hasta q vuelva del gps");
           }
       }

    );
    editTextSearch.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            if (actionId == EditorInfo.IME_ACTION_SEARCH) {
                performSearch();
                return true;
            }
            return false;
        }
    });

    search_button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            performSearch();
        }
    });
    return viewRoot;
}


@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == 0) {
        setNameGPSButton();
    }
}

private void performSearch(){
    final Fragment fragment = this;
    closeKeyboard();
    String placeToSearch = editTextSearch.getText().toString().trim();
    //replaceAll para reemplazar espacios en blanco por & sino genera una
    //consulta invalida.
    if (tracker.getLocation() != null) {
        try {
            String tempSQL = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?"
                    + "location=" + tracker.getLatitude() + "," + tracker.getLongitude()
                    + "&name=" +  placeToSearch.replaceAll("\\s","&")
                    + "&rankby=distance"
                    + "&key=" + API_KEY;
            Log.d("ATENCION",tempSQL);
            googlePlacesRequest = new GooglePlacesRequest(fragment);
            googlePlacesRequest.execute(tempSQL);
        } catch (Exception e) {
            Log.d("ERROR", e.getMessage());
        }
    } else {
        try {
            ArrayList<Category> categories = dbAdapter.getAllCategoriesThatMatchWith(placeToSearch);
            loadCategoriesInrResultList(categories);
            closeKeyboard();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

private void closeKeyboard(){
    InputMethodManager inputManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
    inputManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}

private void loadCategoriesInrResultList(ArrayList<Category> categories){
    ArrayList<String> catNames = new ArrayList<>();
    for (Category c : categories) {
        catNames.add(c.getName());
    }
    result_count.setText("Resultados:"+ catNames.size());
    ArrayAdapter adapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_list_item_1, catNames);
    categoryPlaceListview.setAdapter(adapter);
    categoryPlaceListview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
            String category = adapterView.getAdapter().getItem(position).toString();
            OnPlaceSelectedListener listener = (OnPlaceSelectedListener) getActivity();
            try {
                //Category cat = dbAdapter.getCategoryLikeFromPlace(placesList.getPlace(place));
                Category cat = dbAdapter.getCategoryFromSpanishName(category);
                //en caso de que no exista la categoria, habria q recomendar q la cree
                //xq es muy limitado
                Toast.makeText(getActivity(), "Modo: " + cat.getName() + " seleccionado correctamente", Toast.LENGTH_SHORT).show();
                listener.onPlaceSelected(cat);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    });
}

private void populateListviewPlaces(ArrayList<String> adapterPlaces) {
    final ArrayAdapter<String> adapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1, adapterPlaces);
    categoryPlaceListview.setAdapter(adapter);
    categoryPlaceListview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
            String place = adapterView.getAdapter().getItem(position).toString();
            //obtener la categoria en ingles,
            // utilizar el servicio de traductor (no se q tan bueno sera)
            //y si no existe recomendar que cree una categoria nueva del administrador de frases
            //con ese nombre.
            OnPlaceSelectedListener listener = (OnPlaceSelectedListener)getActivity();
            //obtengo la categoria a partir del lugar y
            //comunico a MainActivity la categoria
            try {
                Category cat = dbAdapter.getCategoryLikeFromPlace(placesList.getPlace(place));
                if(cat != null){
                    Toast.makeText(getActivity(), "Modo: " +cat.getName()+" seleccionado correctamente", Toast.LENGTH_SHORT).show();
                    listener.onPlaceSelected(cat);
                }
                else{
                    String categoryToAdd = dbAdapter.getCategoryToAdd(placesList.getPlace(place));
                    CreateCategoryOptionDialog createCategoryOptionDialog = new CreateCategoryOptionDialog(categoryToAdd);
                    createCategoryOptionDialog.show(getFragmentManager(),"Nueva Categoria");

                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    });
}
private ArrayList<String> createListAdapter(PlacesList placesList) {
    //crea el arraylist con nombres para utilizarlo como adapter.
    ArrayList<String> namesPlaces = new ArrayList<>();
    for(String key: placesList.getResults().keySet()){
        namesPlaces.add(key);
    }
    return namesPlaces;
}
@Override
//cuando se ejecuta onPostExecute() es que termina de cargar
// procesamos los datos aca
public void placesFinishedLoading(String output) {
    placesList = googlePlacesRequest.getPlacesList();
    adapterPlaces = createListAdapter(placesList);
    populateListviewPlaces(adapterPlaces);
    result_count.setText("Resultados:" + adapterPlaces.size());
}
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#ffffff">
        <android.support.v4.view.ViewPager
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">
            <android.support.v4.view.PagerTabStrip
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="top"
                android:paddingBottom="10dp"
                android:paddingTop="20dp"
                android:layout_marginTop="100dp"
                android:background="@color/colorPrimary"
                android:textAppearance="@style/PagerTabStripText"/>
        </android.support.v4.view.ViewPager>

    </android.support.design.widget.AppBarLayout>

fragment_places_categories_admin.xml

<LinearLayout 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:orientation="vertical"
tools:context=".fragments.PlacesCategoriesAdmin"
android:weightSum="1"
android:id="@+id/places_search">

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/buttonGPS" />

<EditText
    android:layout_width="357dp"
    android:layout_height="wrap_content"
    android:id="@+id/searchFieldCatPlace"
    android:hint="@string/search_place_cat"
    android:layout_margin="10dp"
    android:imeOptions="actionSearch"
    android:inputType="text"
    />

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/search_button"
    android:id="@+id/search_place_gps" />

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/result_count_text"
    android:padding="10dp"
    android:layout_margin="10dp"
    android:text="@string/result_text"
    android:textSize="20sp"
    android:textAlignment="center"/>


<ListView
    android:layout_width="wrap_content"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:id="@+id/listview_category_place">


</ListView>

Any ideas? Thanks in advance!

Upvotes: 0

Views: 285

Answers (1)

Fabio Venturi Pastor
Fabio Venturi Pastor

Reputation: 2529

Try this:

yourListView.setOnTouchListener(new ListView.OnTouchListener() {
      @Override
      public boolean onTouch(View v, MotionEvent event) {
      int action = event.getAction();
      switch (action) {
         case MotionEvent.ACTION_DOWN:
          v.getParent().requestDisallowInterceptTouchEvent(true);
          break;
         case MotionEvent.ACTION_UP:     
          v.getParent().requestDisallowInterceptTouchEvent(false);
          break;
         }
       v.onTouchEvent(event);
      return true;
     }
});

Upvotes: 1

Related Questions