Reputation: 612
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
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