Fragment、Volley 和 RecyclerView
Posted
技术标签:
【中文标题】Fragment、Volley 和 RecyclerView【英文标题】:Fragment, Volley and RecyclerView 【发布时间】:2018-04-18 02:54:29 【问题描述】:我希望有人可以帮助我解决我的问题。我有 3 个选项卡的 android 应用程序,我使用片段,第一个选项卡是 recyclerView 列表,第二个选项卡是地图。问题出在选项卡 1 中,我需要使用 volley 将数据获取到选项卡 1 上的 recyclerView,如果运行正常但我在第一个应用程序启动时看不到数据,但是当我更改选项卡并再次返回选项卡 1 时,它将刷新数据并在 recyclerView 上显示数据。
Adapter.java
public class CustomListAdapterWarkop extends RecyclerView.Adapter<RecyclerView.ViewHolder>
private Context context;
private List<Warkop> mWarkop;
private LayoutInflater inflater;
public CustomListAdapterWarkop(Context context, List<Warkop> mWarkop)
this.context=context;
inflater= LayoutInflater.from(context);
this.mWarkop = mWarkop;
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
View view = inflater.inflate(R.layout.list_warkop_row, parent, false);
ItemViewHolder holder = new ItemViewHolder(view);
return holder;
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
ItemViewHolder viewHolder = (ItemViewHolder) holder;
Warkop current = mWarkop.get(position);
viewHolder.tvNamaWarkop.setText(current.getNamaWarkop());
ImageLoader imageLoader = ImageLoader.getInstance();
DisplayImageOptions options = new DisplayImageOptions.Builder().cacheInMemory(true)
.cacheOnDisc(true).resetViewBeforeLoading(true)
.showImageForEmptyUri(R.drawable.noimage)
.showImageOnFail(R.drawable.noimage)
.showImageOnLoading(R.drawable.noimage).build();
imageLoader.displayImage(current.getFotoWarkop(), viewHolder.ivFotoWarkop, options);
@Override
public int getItemCount()
return mWarkop.size();
ItemHolder.java
package com.andylah.warkopedia;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
/**
* Created by andylah on 11/3/2017.
*/
public class ItemViewHolder extends RecyclerView.ViewHolder
public ImageView ivFotoWarkop;
public TextView tvNamaWarkop;
public ItemViewHolder(View itemView)
super(itemView);
tvNamaWarkop = itemView.findViewById(R.id.nama_warkop);
ivFotoWarkop = itemView.findViewById(R.id.image_warkop);
标签 1.java
public class tabSatu extends Fragment
private static final String TAG = tabDua.class.getSimpleName();
public static final int CONNECTION_TIMEOUT = 10000;
public static final int READ_TIMEOUT = 15000;
private boolean isFragmentLoaded = false;
View vTabSatu;
private RecyclerView recyclerView;
public static List<Warkop> warkopList = new ArrayList<Warkop>();
private CustomListAdapterWarkop warkopAdapter;
public tabSatu()
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
new AsyncFetch().execute();
vTabSatu = inflater.inflate(R.layout.tabsatu_view, container, false);
recyclerView = vTabSatu.findViewById(R.id.warkop_container);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
Log.d("LOG : ", "onCreatedView Run");
// Inflate the layout for this fragment
return vTabSatu;
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
warkopAdapter = new CustomListAdapterWarkop(getActivity(), warkopList);
warkopAdapter.notifyDataSetChanged();
recyclerView.setAdapter(warkopAdapter);
Log.d("LOG : ", "onViewCreated Run");
@Override
public void setUserVisibleHint(boolean isVisibleToUser)
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser && !isFragmentLoaded )
// Load your data here or do network operations here
isFragmentLoaded = true;
//new AsyncFetch().execute();
else
isFragmentLoaded = false;
Log.d("LOG : ", "isFragmentLoaded = false");
private class AsyncFetch extends AsyncTask<String, String, String>
ProgressDialog pDialog = new ProgressDialog(getActivity());
HttpURLConnection conn;
URL url = null;
@Override
protected void onPreExecute()
super.onPreExecute();
pDialog.setMessage("Loading list warkop ...");
pDialog.setCancelable(false);
pDialog.show();
@Override
protected String doInBackground(String... strings)
try
// Enter URL address where your json file resides
// Even you can make call to php file which returns json data
url = new URL(AppConfig.LOAD_WARKOP);
catch (MalformedURLException e)
// TODO Auto-generated catch block
e.printStackTrace();
return e.toString();
try
// Setup HttpURLConnection class to send and receive data from php and mysql
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("POST");
// setDoOutput to true as we recieve data from json file
conn.setDoOutput(true);
catch (IOException e1)
// TODO Auto-generated catch block
e1.printStackTrace();
return e1.toString();
try
int response_code = conn.getResponseCode();
// Check if successful connection made
if (response_code == HttpURLConnection.HTTP_OK)
// Read data sent from server
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null)
result.append(line);
// Pass data to onPostExecute method
return (result.toString());
else
return ("unsuccessful");
catch (IOException e)
e.printStackTrace();
return e.toString();
finally
conn.disconnect();
@Override
protected void onPostExecute(String result)
pDialog.dismiss();
try
JSONObject object = new JSONObject(result);
String getObject = object.getString("warkop");
JSONArray jsonArray = new JSONArray(getObject);
boolean error = object.getBoolean("error");
if(!error)
for (int i = 0; i < jsonArray.length(); i++)
JSONObject jsonObject = jsonArray.getJSONObject(i);
Warkop warkop = new Warkop();
warkop.setNamaWarkop(jsonObject.getString("nama_warkop"));
warkop.setAlamatWrkop(jsonObject.getString("alamat_warkop"));
warkop.setKotaWarkop(jsonObject.getString("kota_warkop"));
warkop.setLatWarkop(Double.parseDouble(jsonObject.getString("lat_warkop")));
warkop.setLangWarkop(Double.parseDouble(jsonObject.getString("long_warkop")));
warkop.setIsWifi(Integer.parseInt(jsonObject.getString("is_wifi")));
warkop.setIsToilet(Integer.parseInt(jsonObject.getString("is_toilet")));
warkop.setIsTv(Integer.parseInt(jsonObject.getString("is_tv")));
warkop.setIsColokan(Integer.parseInt(jsonObject.getString("is_colokan")));
warkop.setIsParkir(Integer.parseInt(jsonObject.getString("is_parkir")));
warkop.setFotoWarkop(jsonObject.getString("foto_warkop"));
warkopList.add(warkop);
else
String errorMsg = object.getString("error_msg");
Toast.makeText(getContext(),
errorMsg, Toast.LENGTH_LONG).show();
catch (JSONException e)
e.printStackTrace();
Toast.makeText(getActivity(), "Json error: " + e.getMessage(), Toast.LENGTH_LONG).show();
【问题讨论】:
【参考方案1】:问题:即使您调用notifyDataSetChanged()
,但适配器中没有数据。
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
warkopAdapter = new CustomListAdapterWarkop(getActivity(), warkopList);
warkopAdapter.notifyDataSetChanged();
recyclerView.setAdapter(warkopAdapter);
所以你需要在 API 调用后设置并通知warkopList
到Adapter
。它会帮助你。
tabSatu:
@Override
protected void onPostExecute(String result)
pDialog.dismiss();
try
JSONObject object = new JSONObject(result);
String getObject = object.getString("warkop");
JSONArray jsonArray = new JSONArray(getObject);
boolean error = object.getBoolean("error");
if (!error)
for (int i = 0; i < jsonArray.length(); i++)
JSONObject jsonObject = jsonArray.getJSONObject(i);
Warkop warkop = new Warkop();
...
warkopList.add(warkop);
adapter.setItems(warkopList);
...
CustomListAdapterWarkop:将setItem()
方法添加到适配器
public class CustomListAdapterWarkop extends RecyclerView.Adapter<RecyclerView.ViewHolder>
...
public void setItems(List<WarkopList> warkopList)
mWarkop = warkopList;
notifyDataSetChanged();
...
【讨论】:
以上是关于Fragment、Volley 和 RecyclerView的主要内容,如果未能解决你的问题,请参考以下文章