У меня есть представление переработчика, чьи соперничества видимых элементов не обновляются, когда вызывается notifyDataSetChanged(). Невидимые элементы обновляются без проблем.
Я видел, что это была проблема с просмотром списка, как указано здесь: представление списка уже не обновляется видимые элементы
Но я не знаю, что делать с просмотром переработчика. В моем адаптере представления ресайклера я динамически добавляю представления в соответствии с моим кодом.
Вот мой код:
public class Nearby_Viewpager_Stops extends Fragment {
private final String TAG = "Nearby Stops";
View mRootview = null;
RecyclerView mRecyclerView;
MKLoader mProgressBar;
Context mContext;
TextView mNoStopsTV;
Nearby_Stops_Adapter mStops_adapter;
List<BusArrivalPOJO> mBusArrivalPOJOList = new ArrayList<>();
List<List<BusArrivalPOJO>> mBusArrivalDetailsPOJOList = new ArrayList<>();
LinearLayoutManager mLayoutManager;
Handler mHandler;
Handler mHandlerForOnStop;
boolean resumed = true;
private static final int REFRESH_TIME = 30;
int lengthOfStopsList;
boolean isNoStops_available_nearby = false;
boolean isFirstTimeCalled;
boolean isRunningFirstTime;
@Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if (mRootview == null) {
mRootview = inflater.inflate(R.layout.nearby_viewpager_stops, container, false);
mRecyclerView = (RecyclerView) mRootview.findViewById(R.id.recycler_view);
mProgressBar = (MKLoader) mRootview.findViewById(R.id.progressBar);
mNoStopsTV = (TextView) mRootview.findViewById(R.id.no_nearby_stops_text);
}
mLayoutManager = new LinearLayoutManager(mContext);
mRecyclerView.setLayoutManager(mLayoutManager);
mStops_adapter = new Nearby_Stops_Adapter(mBusArrivalPOJOList, mBusArrivalDetailsPOJOList);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mRecyclerView.setAdapter(mStops_adapter);
return mRootview;
}
private class GetNearbyStops extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
isNoStops_available_nearby = false;
mProgressBar.setVisibility(View.VISIBLE);
mBusArrivalPOJOList.clear();
pos = mLayoutManager.findFirstVisibleItemPosition();
mStops_adapter.notifyDataSetChanged();
}
@Override
protected Void doInBackground(Void... voids) {
String urlString = "https://api.tfl.gov.uk/StopPoint?radius=2000&stopTypes=NaptanRailStation,NaptanBusCoachStation,NaptanFerryPort,NaptanPublicBusCoachTram&useStopPointHierarchy=true" +
"&modes=bus&lat="+ Constants.latitude+"&lon="+Constants.longitude+"&categories=facility&app_id=" + Constants.app_id_tfl + "&app_key=" + Constants.app_key_tfl;
Log.v(TAG, urlString);
HttpURLConnection urlConnection = null;
BufferedReader bufferedReader;
String line;
InputStream inputStream;
StringBuilder json_result = new StringBuilder();
try {
System.setProperty("http.keepAlive", "false");
URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(2000);
urlConnection.setConnectTimeout(2000);
urlConnection.setRequestMethod("GET");
inputStream = new BufferedInputStream(urlConnection.getInputStream());
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
while ((line = bufferedReader.readLine()) != null) {
json_result.append(line);
}
} catch (Exception e) {
Log.e(TAG, e.getLocalizedMessage());
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
getDataFromJSON(json_result.toString());
return null;
}
private void getDataFromJSON(String json) {
try {
JSONObject jsonObject = new JSONObject(json);
JSONArray stopPoints = jsonObject.getJSONArray("stopPoints");
if (stopPoints.length() <= 20 && stopPoints.length() != 0) {
lengthOfStopsList = stopPoints.length();
} else if (stopPoints.length() == 0) {
lengthOfStopsList = 0;
isNoStops_available_nearby = true;
}
for (int i = 0; i< lengthOfStopsList; i++) {
JSONObject jsonObject1 = stopPoints.getJSONObject(i);
int distance = Math.round(jsonObject1.getInt("distance")/60);
Double lat = jsonObject1.getDouble("lat");
Double lon = jsonObject1.getDouble("lon");
String commonName = jsonObject1.getString("commonName");
JSONArray lineGroup = jsonObject1.getJSONArray("lineGroup");
new GetBusArrivals().execute(lineGroup, new LatLng(lat, lon), distance);
String naptanID;
for (int j=0; j< lineGroup.length(); j++) {
JSONObject jsonObject2 = lineGroup.getJSONObject(j);
if (jsonObject2.has("naptanIdReference")) {
naptanID = jsonObject2.getString("naptanIdReference");
BusArrivalPOJO busArrivalPOJO = new
BusArrivalPOJO(commonName, distance, new LatLng(lat, lon), naptanID);
mBusArrivalPOJOList.add(busArrivalPOJO);
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
mStops_adapter.notifyDataSetChanged();
}
});
}
}
}
} catch (JSONException e) {
Log.e(TAG, e.getLocalizedMessage());
if (getActivity()!=null)
getActivity().runOnUiThread(new Runnable() {
public void run() {
new GetNearbyStops().execute();
}
});
}
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if (isNoStops_available_nearby) {
mProgressBar.setVisibility(View.GONE);
mNoStopsTV.setVisibility(View.VISIBLE);
} else {
mProgressBar.setVisibility(View.VISIBLE);
mNoStopsTV.setVisibility(View.GONE);
}
}
}
int pos;
private class GetBusArrivals extends AsyncTask<Object, Void, Void> {
/**
* It represents the position of the first visible position of recycler view
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
if (isFirstTimeCalled) {
if (getActivity() != null)
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
mBusArrivalDetailsPOJOList.clear();
mStops_adapter.notifyDataSetChanged();
}
});
isFirstTimeCalled = false;
}
}
LatLng latLng;
String stopID;
int distance;
@Override
protected Void doInBackground(Object... strings) {
JSONArray lineGroup = (JSONArray) strings[0];
latLng = (LatLng) strings[1];
distance = (int) strings[2];
try {
for (int j=0; j< lineGroup.length(); j++) {
JSONObject jsonObject2 = lineGroup.getJSONObject(j);
if (jsonObject2.has("naptanIdReference")) {
stopID = jsonObject2.getString("naptanIdReference");
String urlString = "https://api.tfl.gov.uk/StopPoint/"+stopID+"/Arrivals?app_id="
+ Constants.app_id_tfl + "&app_key=" + Constants.app_key_tfl;
HttpURLConnection urlConnection = null;
BufferedReader bufferedReader;
String line;
InputStream inputStream;
StringBuilder json_result = new StringBuilder();
try {
Log.v(TAG, urlString);
System.setProperty("http.keepAlive", "false");
URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(2000);
urlConnection.setConnectTimeout(2000);
urlConnection.setRequestMethod("GET");
inputStream = new BufferedInputStream(urlConnection.getInputStream());
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
while ((line = bufferedReader.readLine()) != null) {
json_result.append(line);
}
List<BusArrivalPOJO> busArrivalPOJOs = getDataFromJSON(json_result.toString(), latLng, distance);
if (busArrivalPOJOs != null) {
mBusArrivalDetailsPOJOList.add(busArrivalPOJOs);
Log.v("length", "leng"+mBusArrivalDetailsPOJOList.size());
if (getActivity() != null) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (mProgressBar.getVisibility() == View.VISIBLE)
mProgressBar.setVisibility(View.GONE);
if (mBusArrivalDetailsPOJOList.size() < 5) {
mRecyclerView.setAdapter(mStops_adapter);
} else
mStops_adapter.notifyDataSetChanged();
}
});
}
}
} catch (Exception e) {
j= j-1;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
}
}
} catch (JSONException e) {
Log.e(TAG, e.getLocalizedMessage());
}
return null;
}
private List<BusArrivalPOJO> getDataFromJSON(String json, LatLng latLng, int distance) {
List<BusArrivalPOJO> busArrivalPOJOList = new ArrayList<>();
try {
Log.v(TAG, json);
JSONArray jsonArray = new JSONArray(json);
for (int i=0; i< jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
if (jsonObject.has("exceptionType") && jsonObject.getString("exceptionType").contentEquals("EntityNotFoundException")) {
return null;
} else {
String lineName = jsonObject.getString("lineName");
String platformName = jsonObject.getString("platformName");
String destinationName = jsonObject.getString("destinationName");
int timeToArrivalToStation = jsonObject.getInt("timeToStation");
String stationName = jsonObject.getString("stationName");
String naptanId = jsonObject.getString("naptanId");
BusArrivalPOJO busArrivalPOJO = new BusArrivalPOJO(lineName, platformName, destinationName,
timeToArrivalToStation, stationName, latLng, distance, naptanId);
busArrivalPOJOList.add(busArrivalPOJO);
}
}
} catch (JSONException e) {
Log.e(TAG, e.getLocalizedMessage());
}
return busArrivalPOJOList;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if (pos< mBusArrivalPOJOList.size()-5 && mBusArrivalPOJOList.size()-5 == mBusArrivalDetailsPOJOList.size()
|| mBusArrivalDetailsPOJOList.size() == mBusArrivalPOJOList.size()) {
}
if (MainActivity.menuItem != null && MainActivity.menuItem.getActionView() != null) {
MainActivity.menuItem.getActionView().clearAnimation();
MainActivity.menuItem.setActionView(null);
}
}
}
@Override
public void onResume() {
super.onResume();
mHandler = new Handler();
resumed = true;
isRunningFirstTime = true;
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
isFirstTimeCalled = true;
new GetNearbyStops().execute();
mHandler.postDelayed(this, REFRESH_TIME * 1000);
}
}, 1000);
}
}
Вот код моего адаптера представления recycler:
class Nearby_Stops_Adapter extends RecyclerView.Adapter {
private List<List<BusArrivalPOJO>> mBusArrivalPOJOListFullDetails = new ArrayList<>();
private List<BusArrivalPOJO> mBusArrivalPOJOList = new ArrayList<>();
Context mContext;
private LinearLayout mLinearLayout;
private static HashSet<String> isRemainingTimesOpen = new HashSet<>();
private final String TAG = "NearbyStopsAda";
Nearby_Stops_Adapter(List<BusArrivalPOJO> busArrivalPOJOList,List<List<BusArrivalPOJO>> busArrivalPOJOList1 ) {
mBusArrivalPOJOList = busArrivalPOJOList;
mBusArrivalPOJOListFullDetails = busArrivalPOJOList1;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View rootView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.nearby_stops_adapter,parent,false);
mContext = parent.getContext();
mLinearLayout = (LinearLayout) rootView.findViewById(R.id.linear_layout);
TextView mStationName = (TextView) rootView.findViewById(R.id.stationName);
mStationName.setTypeface(Typeface.create("sans-serif-medium", Typeface.NORMAL));
MKLoader progressBar = (MKLoader) rootView.findViewById(R.id.progressBar);
TextView timeToWalkToStation = (TextView) rootView.findViewById(R.id.timeToTravel);
CardView cardView = (CardView) rootView.findViewById(R.id.cardView);
return new Nearby_Stops_Adapter.ViewHolder(rootView, mStationName, timeToWalkToStation, cardView, progressBar);
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
if (mBusArrivalPOJOList.size() > 0) {
((ViewHolder) holder).stationNameTV.setText(mBusArrivalPOJOList.get(position).getStationName());
String time = mBusArrivalPOJOList.get(position).getTimeToWalkToStation() + " min";
((ViewHolder) holder).timeToWalkToStation.setText(time);
}
if (mBusArrivalPOJOListFullDetails.size()>0) {
mLinearLayout.removeAllViews();
for (int a=0; a< mBusArrivalPOJOListFullDetails.size() ;a++) {
if (mBusArrivalPOJOList.get(position).getStationID()
.contentEquals(mBusArrivalPOJOListFullDetails.get(a).get(0).getStationID())) {
if (!mBusArrivalPOJOListFullDetails.get(a).get(0).getPlatformName().contentEquals("null"))
if (!((ViewHolder) holder).stationNameTV.getText().toString().contains("::"))
((ViewHolder) holder).stationNameTV.append(" :: "+mBusArrivalPOJOListFullDetails.get(a).get(0).getPlatformName());
for (int j=0; j< mBusArrivalPOJOListFullDetails.get(a).size() ;j++) {
Collections.sort(mBusArrivalPOJOListFullDetails.get(a), new Comparator<BusArrivalPOJO>() {
@Override
public int compare(BusArrivalPOJO busArrivalPOJO, BusArrivalPOJO t1) {
return busArrivalPOJO.getTimeToArrival() - t1.getTimeToArrival();
}
});
}
Set<String> uniqueBusNamesSet = new HashSet<>();
for (int m = 0; m< mBusArrivalPOJOListFullDetails.get(a).size() ;m++) {
uniqueBusNamesSet.add(mBusArrivalPOJOListFullDetails.get(a).get(m).getBusName());
}
ArrayList<Multimap<String, Integer>> allBusesForParticularStation = new ArrayList<>();
for (String key: uniqueBusNamesSet) {
Multimap<String, Integer> busWithTimes = ArrayListMultimap.create();
for (int s=0; s< mBusArrivalPOJOListFullDetails.get(a).size() ;s++) {
if (key.contentEquals(mBusArrivalPOJOListFullDetails.get(a).get(s).getBusName())) {
busWithTimes.put(key +"::"+ mBusArrivalPOJOListFullDetails.get(a).get(s).getDestinationName()
, mBusArrivalPOJOListFullDetails.get(a).get(s).getTimeToArrival());
}
}
allBusesForParticularStation.add(busWithTimes);
}
((ViewHolder) holder).progressBar.setVisibility(View.GONE);
for (int t=0 ; t< allBusesForParticularStation.size() ;t++) {
Multimap<String, Integer> map = allBusesForParticularStation.get(t);
for (String key: map.keySet()) {
List<Integer> values = new ArrayList<>(map.get(key));
RelativeLayout relativeLayout = new RelativeLayout(mContext);
relativeLayout.setPadding(16, 16, 16, 16);
LinearLayout linearLayoutForBusName = new LinearLayout(mContext);
linearLayoutForBusName.setOrientation(LinearLayout.VERTICAL);
final TextView busNameTV = new TextView(mContext);
busNameTV.setText(key.split("::")[0]);
busNameTV.setTypeface(Typeface.create("sans-serif-normal", Typeface.NORMAL));
busNameTV.setTextColor(ContextCompat.getColor(mContext,R.color.colorTextPrimary));
final TextView destinationNameTV = new TextView(mContext);
destinationNameTV.setText(key.split("::")[1]);
destinationNameTV.setTextSize(12);
destinationNameTV.setTextColor(ContextCompat.getColor(mContext,R.color.colorTextSecondary));
linearLayoutForBusName.addView(busNameTV);
linearLayoutForBusName.addView(destinationNameTV);
LinearLayout linearLayoutForTimes = new LinearLayout(mContext);
linearLayoutForTimes.setOrientation(LinearLayout.VERTICAL);
RelativeLayout timeRelativeLayout = new RelativeLayout(mContext);
timeRelativeLayout.setId(R.id.time_relativeLayout_id);
LinearLayout timeArrowLinearLayout = new LinearLayout(mContext);
timeArrowLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
timeArrowLinearLayout.setId(R.id.time_id);
timeArrowLinearLayout.setGravity(Gravity.CENTER_VERTICAL);
timeArrowLinearLayout.setPadding(6,6,6,6);
RelativeLayout.LayoutParams timeArrowLP = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
timeArrowLP.addRule(RelativeLayout.RIGHT_OF, R.id.time_tv);
timeArrowLP.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
timeArrowLinearLayout.setLayoutParams(timeArrowLP);
//Recent Time text view
TextView timeTV = new TextView(mContext);
int timeSec = values.get(0);
int timeInMin = Math.round(timeSec / 60);
if (timeInMin == 0) {
String timeText = "due";
timeTV.setText(timeText);
} else {
String timeInMinText = timeInMin + " min";
timeTV.setText(timeInMinText);
}
timeTV.setTextColor(ContextCompat.getColor(mContext, R.color.textColorAccent));
timeTV.setPadding(0,0,16,0);
final TextView remainingTimesTV = new TextView(mContext);
remainingTimesTV.setTextColor(ContextCompat.getColor(mContext, R.color.colorTextSecondary));
remainingTimesTV.setTextSize(11);
remainingTimesTV.setVisibility(View.GONE);
for (int l=1; l< values.size() && l < 4; l++) {
String tempTime;
if (l == 3 || l == values.size() - 1) {
tempTime = values.get(l) / 60 + " min";
}
else
tempTime = values.get(l)/60 + " min, ";
remainingTimesTV.append(tempTime);
}
RelativeLayout.LayoutParams remainingTimeLayoutParams = new RelativeLayout.LayoutParams
(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
remainingTimeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
remainingTimeLayoutParams.addRule(RelativeLayout.BELOW, R.id.time_id);
remainingTimesTV.setLayoutParams(remainingTimeLayoutParams);
timeArrowLinearLayout.addView(timeTV);
if (values.size() > 1) {
//Down arrow button
final ImageView imageButton = new ImageView(mContext);
imageButton.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.arrow_down));
if (isRemainingTimesOpen != null) {
for (String openedRowKey : isRemainingTimesOpen) {
if (openedRowKey.contains(busNameTV.getText().toString()) &&
openedRowKey.contains(destinationNameTV.getText().toString()) &&
openedRowKey.contains(((ViewHolder) holder).stationNameTV.getText().toString())) {
remainingTimesTV.setVisibility(View.VISIBLE);
imageButton.setImageResource(R.drawable.arrow_top);
}
}
}
timeArrowLinearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (remainingTimesTV.getVisibility() == View.GONE) {
isRemainingTimesOpen.add(busNameTV.getText().toString()
+destinationNameTV.getText().toString()
+(((ViewHolder) holder).stationNameTV.getText().toString()));
remainingTimesTV.setVisibility(View.VISIBLE);
imageButton.setImageResource(R.drawable.arrow_down);
imageButton.animate().rotation(180).start();
} else {
remainingTimesTV.setVisibility(View.GONE);
imageButton.setImageResource(R.drawable.arrow_top);
imageButton.animate().rotation(-180).start();
}
}
});
timeArrowLinearLayout.addView(imageButton);
}
RelativeLayout.LayoutParams layoutParams2 = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams2.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
layoutParams2.addRule(RelativeLayout.CENTER_VERTICAL);
timeRelativeLayout.setLayoutParams(layoutParams2);
timeRelativeLayout.addView(timeArrowLinearLayout);
timeRelativeLayout.addView(remainingTimesTV);
View horLine = new View(mContext);
RelativeLayout.LayoutParams layoutParams3 = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
1);
horLine.setLayoutParams(layoutParams3);
horLine.setBackgroundColor(ContextCompat.getColor(mContext, R.color.horizontal_line));
horLine.setPadding(0,5,0,5);
relativeLayout.addView(linearLayoutForBusName);
relativeLayout.addView(timeRelativeLayout);
((ViewHolder) holder).cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
mLinearLayout.addView(relativeLayout);
if (t < uniqueBusNamesSet.size()-1) {
mLinearLayout.addView(horLine);
}
}
}
}
}
}
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemCount() {
return mBusArrivalPOJOList.size();
}
private class ViewHolder extends RecyclerView.ViewHolder {
TextView stationNameTV;
TextView timeToWalkToStation;
CardView cardView;
MKLoader progressBar;
ViewHolder(View view, TextView stationNameTV, TextView timeToWalkToStation, CardView cardView,
MKLoader progressBar) {
super(view);
this.stationNameTV = stationNameTV;
this.timeToWalkToStation = timeToWalkToStation;
this.cardView = cardView;
this.progressBar = progressBar;
}
}
}