Reputation: 1303
Complete noob here so bear with me. I've got an activity that loads data from my server and shows it in a Listview. Now I need to be able to re-order that list based on a TabHost. I'm using MaterialTabHost (https://github.com/neokree/MaterialTabs)
Here's the code I use to populate the listview:
listView = (ListView) findViewById(R.id.list);
adapter = new CustomListAdapter(this, movieList);
listView.setAdapter(adapter);
pDialog = new ProgressDialog(this);
// Showing progress dialog before making http request
pDialog.setMessage("Loading...");
pDialog.show();
// Creating volley request obj
final Double finalLat = lat;
final Double finalLon = lon;
final Double finalLat1 = lat;
final Double finalLon1 = lon;
JsonArrayRequest movieReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(final JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
viewer movie = new viewer();
LatLng point1 = new LatLng(obj.getDouble("lat"), obj.getDouble("long"));
LatLng point2 = new LatLng(finalLat, finalLon);
distanceInMiles = LatLngTool.distance(point1, point2, LengthUnit.MILE);
movie.setTitle(obj.getString("first_name"));
movie.setThumbnailUrl(obj.getString("pic"));
//movie.setRating(((String) obj.getString("experience")));
movie.setYear(Double.parseDouble(String.format("%.2f", distanceInMiles)));
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String clicked_at = null;
try {
clicked_at = response.getString(position);
} catch (JSONException e) {
e.printStackTrace();
}
Intent i = new Intent(getApplicationContext(), full_view_walker.class);
i.putExtra("data", clicked_at);
i.putExtra("lat", finalLat1);
i.putExtra("lon", finalLon1);
i.putExtra("sender_id", sender_id);
startActivity(i);
}
});
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(movieReq);
}
Now my tab stuff:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.user_listview);
tabHost = (MaterialTabHost) this.findViewById(R.id.tabHost);
pager = (ViewPager) this.findViewById(R.id.pager);
// init view pager
adapter_page = new ViewPagerAdapter(getSupportFragmentManager());
pager.setAdapter(adapter_page);
pager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
// when user do a swipe the selected tab change
tabHost.setSelectedNavigationItem(position);
}
});
// insert all tabs from pagerAdapter data
for (int i = 0; i < adapter_page.getCount(); i++) {
tabHost.addTab(
tabHost.newTab()
.setText(adapter_page.getPageTitle(i))
.setTabListener(this)
);
}
@Override
public void onTabSelected(MaterialTab tab) {
pager.setCurrentItem(tab.getPosition()); }
private class ViewPagerAdapter extends FragmentStatePagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
public Fragment getItem(int num) {
return new FragmentText();
}
@Override
public int getCount() {
return 3;
}
private String[] lst = {"Distance", "Experience", "History"};
@Override
public CharSequence getPageTitle(int position) {
return lst[position];
}
}
And I have FragmentText here:
public class FragmentText extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.front_list, container, false);
}
}
Now I really need 2 things:
1) How to connect the inflater.inflate in FragmentText to the code that loads the list and populates it? 2) How to make sure it doesn't have to reload each time the user switches tabs, and that the list is loaded/sorted once and then will just reload from there?
Edit: I tried this in FragmentText:
public class FragmentText extends Fragment{
// Log tag
private static final String TAG = AvailableList.class.getSimpleName();
String sender_id;
double distanceInMiles;
Double lat = null;
Double lon = null;
private ProgressDialog pDialog;
private List<viewer> movieList = new ArrayList<viewer>();
private ListView listView;
private CustomListAdapter adapter;
private String[] leftSliderData = {"Logout", "Contact Us"};
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
lon = getArguments().getDouble("lon");
lat = getArguments().getDouble("lat");
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View V = inflater.inflate(R.layout.front_list, container, false);
listView = (ListView) V.findViewById(R.id.list);
adapter = new CustomListAdapter(getActivity(), movieList);
Log.d("Adapter", adapter.toString()+"");
listView.setAdapter(adapter);
final Double finalLat = lat;
final Double finalLon = lon;
final Double finalLat1 = lat;
final Double finalLon1 = lon;
JsonArrayRequest movieReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(final JSONArray response) {
Log.d(TAG, response.toString());
//hidePDialog();
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
viewer movie = new viewer();
LatLng point1 = new LatLng(obj.getDouble("lat"), obj.getDouble("long"));
LatLng point2 = new LatLng(finalLat, finalLon);
distanceInMiles = LatLngTool.distance(point1, point2, LengthUnit.MILE);
movie.setTitle(obj.getString("first_name"));
movie.setThumbnailUrl(obj.getString("pic"));
movie.setYear(Double.parseDouble(String.format("%.2f", distanceInMiles)));
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String clicked_at = null;
try {
clicked_at = response.getString(position);
} catch (JSONException e) {
e.printStackTrace();
}
Intent i = new Intent(getActivity(), full_view_walker.class);
i.putExtra("data", clicked_at);
i.putExtra("lat", finalLat1);
i.putExtra("lon", finalLon1);
i.putExtra("sender_id", sender_id);
startActivity(i);
}
});
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
//hidePDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(movieReq);
return V;
}
This is loading the pages when I hit a tab, but they aren't showing! I can see the activity of the list being loaded, though!
Upvotes: 0
Views: 659
Reputation: 87064
1) How to connect the inflater.inflate in FragmentText to the code that loads the list and populates it?
There isn't something special besides what you've posted, which should work.
This is loading the pages when I hit a tab, but they aren't showing!
Is the first tab showing data?
You use a ViewPager
with 3 pages containing the same fragment so you have the same layout across all pages. In many of this cases, where the ViewPager has the same fragment as page content, the behavior you describe happens because users look for the widgets of various pages directly in the activity layout with findViewById(). findViewById() will return the first occurrence of that view in the layout so you'll always get the views from the first page and any other page besides page 0 will show nothing although the data loads(and gets set on the widgets from the first page, which is not showing). However, in the last code snippet you look for the ListView in the inflated layout so this isn't the problem(in the first code snippet you look for the ListView with simple findViewById(), unclear?) so you may want to look at your layouts and check them for problems.
Another question is if all FragmentText load the same data("url" the same?). If yes, then you shouldn't be doing that network call in each fragment(wasteful), instead you should have a single point making the network call and the fragments using that single point(a good option would be a no UI fragment with setRetainInstance() set to true).
How to make sure it doesn't have to reload each time the user switches tabs, and that the list is loaded/sorted once and then will just reload from there?
The same question as above. Is the same list of data in each of those 3 FragmentText? If yes and those tabs just sort data based on some criteria(distance, experience etc) than have a single list of data and pass an identifier to FragmentText to know what sorting should be done there. Then, when the fragment becomes visible(check setUserVisibleHint()) sort the single list of data based on the criteria for that page and show it to the user.
Upvotes: 1