从 TabHost 填充 Listview 片段
Populating Listview fragment from TabHost
这里完全是菜鸟,请多多包涵。我有一个 activity 从我的服务器加载数据并将其显示在列表视图中。现在我需要能够根据 TabHost 重新排序该列表。我正在使用 MaterialTabHost (https://github.com/neokree/MaterialTabs)
这是我用来填充列表视图的代码:
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);
}
现在我的标签内容:
@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];
}
}
我这里有 FragmentText:
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);
}
}
现在我真的需要两件事:
1) 如何将 FragmentText 中的 inflater.inflate 连接到加载列表并填充它的代码?
2) 如何确保它不必在每次用户切换选项卡时都重新加载,并且列表是 loaded/sorted 一次然后从那里重新加载?
编辑:我在 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;
}
当我点击一个标签时,这正在加载页面,但它们没有显示!不过,我可以看到正在加载列表的 activity!
1) How to connect the inflater.inflate in FragmentText to the code
that loads the list and populates it?
除了您发布的内容之外,没有其他特别之处,但应该有效。
This is loading the pages when I hit a tab, but they aren't showing!
第一个选项卡显示数据吗?
您使用 ViewPager
3 个包含相同片段的页面,因此所有页面的布局都相同。在许多这种情况下,ViewPager 具有与页面内容相同的片段,您描述的行为的发生是因为用户直接在 activity 布局中使用 findViewById() 查找各种页面的小部件。 findViewById() 将 return 该视图在布局中的第一次出现,因此您将始终从第一页获得视图,而除第 0 页之外的任何其他页面将不显示任何内容,尽管数据已加载(并设置在第一页的小部件,未显示)。但是,在最后一个代码片段中,您在膨胀布局中寻找 ListView,所以这不是问题(在第一个代码片段中,您使用简单的 findViewById() 寻找 ListView,不清楚?)所以您可能想看看您的布局并检查它们是否存在问题。
另一个问题是所有的 FragmentText 是否加载相同的数据("url" 相同?)。如果是,那么您不应该在每个片段中进行该网络调用(浪费),而是您应该有一个点进行网络调用和使用该单点的片段(一个好的选择是 no UI setRetainInstance() 设置为 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?
同上题。这 3 个 FragmentText 中的每个数据列表是否相同?如果是,那么这些选项卡只是根据某些标准(距离、经验等)对数据进行排序,而不是使用单个数据列表并将标识符传递给 FragmentText 以了解应该在那里进行什么排序。然后,当片段变为可见时(检查 setUserVisibleHint()),根据该页面的标准对单个数据列表进行排序并将其显示给用户。
这里完全是菜鸟,请多多包涵。我有一个 activity 从我的服务器加载数据并将其显示在列表视图中。现在我需要能够根据 TabHost 重新排序该列表。我正在使用 MaterialTabHost (https://github.com/neokree/MaterialTabs)
这是我用来填充列表视图的代码:
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);
}
现在我的标签内容:
@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];
}
}
我这里有 FragmentText:
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);
}
}
现在我真的需要两件事:
1) 如何将 FragmentText 中的 inflater.inflate 连接到加载列表并填充它的代码? 2) 如何确保它不必在每次用户切换选项卡时都重新加载,并且列表是 loaded/sorted 一次然后从那里重新加载?
编辑:我在 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;
}
当我点击一个标签时,这正在加载页面,但它们没有显示!不过,我可以看到正在加载列表的 activity!
1) How to connect the inflater.inflate in FragmentText to the code that loads the list and populates it?
除了您发布的内容之外,没有其他特别之处,但应该有效。
This is loading the pages when I hit a tab, but they aren't showing!
第一个选项卡显示数据吗?
您使用 ViewPager
3 个包含相同片段的页面,因此所有页面的布局都相同。在许多这种情况下,ViewPager 具有与页面内容相同的片段,您描述的行为的发生是因为用户直接在 activity 布局中使用 findViewById() 查找各种页面的小部件。 findViewById() 将 return 该视图在布局中的第一次出现,因此您将始终从第一页获得视图,而除第 0 页之外的任何其他页面将不显示任何内容,尽管数据已加载(并设置在第一页的小部件,未显示)。但是,在最后一个代码片段中,您在膨胀布局中寻找 ListView,所以这不是问题(在第一个代码片段中,您使用简单的 findViewById() 寻找 ListView,不清楚?)所以您可能想看看您的布局并检查它们是否存在问题。
另一个问题是所有的 FragmentText 是否加载相同的数据("url" 相同?)。如果是,那么您不应该在每个片段中进行该网络调用(浪费),而是您应该有一个点进行网络调用和使用该单点的片段(一个好的选择是 no UI setRetainInstance() 设置为 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?
同上题。这 3 个 FragmentText 中的每个数据列表是否相同?如果是,那么这些选项卡只是根据某些标准(距离、经验等)对数据进行排序,而不是使用单个数据列表并将标识符传递给 FragmentText 以了解应该在那里进行什么排序。然后,当片段变为可见时(检查 setUserVisibleHint()),根据该页面的标准对单个数据列表进行排序并将其显示给用户。