Recyclerview scrolling is not smooth while updating textview item of recyclerview android - android

My app recyclerview having audio, imageview, textview as items. When scrolling the recyclerview, it is scrolled properly without any issue if item is not updated. But scrolling the recyclerview is not smooth while playing a audio item of recyclerview, it behaves as below attached gif image. While playing an audio, i am updating audio current playing time in textview. I am not sure what is issue is here. Kindly help me. Thanks.
Here is my code.
public class MessageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
ArrayList<SessionHistoryMesssage> messageArrayList;
MediaPlayer mPlayer = null;
LocalService mService;
boolean mBound = false;
private RelativeLayout.LayoutParams params;
int currentlyPlayingPosition = -1;
public String mBasePath = "", imageDirectory = "", mSessionId = "", audioDirectory = "";
private ProgressDialog progressDialog;
public RetrofitRestAdapter retrofitRestAdapter;
private MessageAdapter messageListAdapter;
private SessionHistoryResponse sessionHistoryResponse;
public Context mContext;
private int mSelectionPosition = -1;
private int num = 0;
public boolean isSessionStarted=false;
public static Handler mHandler;
public int playposition = -1, sessionstartPosition = -1, alreadystartPosition = -1, sessionendPosition = -1;
public MessageAdapter(Context mContext
, ArrayList<SessionHistoryMesssage> messageArrayList, String mBasePath) {
this.mContext = mContext;
this.messageArrayList = messageArrayList;
this.mBasePath = mBasePath;
mHandler = new Handler();
Intent intent = new Intent(mContext, LocalService.class);
this.mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
// 1. Type a) SEND b) RECEIVE
// 2. Message a) AUDIO b) IMAGE
#Override
public int getItemViewType(int position) {
// Just as an example, return 0 or 2 depending on position
// Note that unlike in ListView adapters, types don't have to be contiguous
Log.i("ViewType", messageArrayList.get(position).getmMediaType() + "");
Log.i("sent by", messageArrayList.get(position).getmSentBy() + "");
return Integer.parseInt(messageArrayList.get(position).getmSentBy());
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
VHItemAudio dataObjectHolder = null;
if (Integer.parseInt(Utility.readPatientId(mContext)) == viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_a_conversation_item, parent, false);
dataObjectHolder = new VHItemAudio(view);
return dataObjectHolder;
} else {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_b_conversation_item, parent, false);
dataObjectHolder = new VHItemAudio(view);
return dataObjectHolder;
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
final VHItemAudio vhItemHolder = (VHItemAudio) holder;
vhItemHolder.bind(messageArrayList.get(position), position);
}
public class VHItemAudio extends RecyclerView.ViewHolder {
ImageView playPauseImageView, imgDownloadAudio, imgDownloadImage;
TextView txtImageSendTime, runningTimerTextView, txtAudioSendTime, txtSessionStart;
SeekBar seekBar;
ImageView imageView;
RelativeLayout layoutAudio, layoutImage, layoutdownloadImage, layoutSessionStart;
ProgressBar progressImageDownload, progressAudioDownload;
private ImageView imageShareImageView,recordAudioImageView,imgEndSession;
public VHItemAudio(View itemView) {
super(itemView);
playPauseImageView = (ImageView) itemView.findViewById(R.id.playPauseImageView);
txtImageSendTime = (TextView) itemView.findViewById(R.id.txtImageSendTime);
runningTimerTextView = (TextView) itemView.findViewById(R.id.runningTimerTextView);
seekBar = (SeekBar) itemView.findViewById(R.id.seekBar);
imgDownloadAudio = (ImageView) itemView.findViewById(R.id.imgDownloadAudio);
imgDownloadImage = (ImageView) itemView.findViewById(R.id.imgDownloadImage);
imageView = (ImageView) itemView.findViewById(R.id.imageView);
txtAudioSendTime = (TextView) itemView.findViewById(R.id.txtAudioSendTime);
layoutAudio = (RelativeLayout) itemView.findViewById(R.id.layoutAudio);
layoutImage = (RelativeLayout) itemView.findViewById(R.id.layoutImage);
layoutdownloadImage = (RelativeLayout) itemView.findViewById(R.id.layoutdownloadImage);
progressImageDownload = (ProgressBar) itemView.findViewById(R.id.progressImageDownload);
progressAudioDownload = (ProgressBar) itemView.findViewById(R.id.progressAudioDownload);
layoutSessionStart = (RelativeLayout) itemView.findViewById(R.id.layoutSessionStart);
txtSessionStart = (TextView) itemView.findViewById(R.id.txtSessionStart);
Log.i("", "Adding Listener");
imageShareImageView= (ImageView) ((PatientActivity)PatientActivity.patientContext).findViewById(R.id.imageShareImageView);
recordAudioImageView= (ImageView) ((PatientActivity) PatientActivity.patientContext).findViewById(R.id.recordAudioImageView);
imgEndSession= (ImageView) ((PatientActivity) PatientActivity.patientContext).findViewById(R.id.imgEndSession);
}
public void bind(final SessionHistoryMesssage sessionHistoryMesssage, final int position) {
if (sessionHistoryMesssage.getmSessionStart().equalsIgnoreCase("yes")
&& Integer.parseInt(sessionHistoryMesssage.getmTransToId())
== Integer.parseInt(Utility.readPatientId(mContext))) {
sessionstartPosition = position;
isSessionStarted=true;
} else if (sessionHistoryMesssage.getmSessionStart().equalsIgnoreCase("already started")) {
alreadystartPosition = position;
} else if (sessionHistoryMesssage.getmSessionStart().equalsIgnoreCase("end")) {
sessionendPosition = position;
} else {
}
if (sessionHistoryMesssage.getmMediaType().equalsIgnoreCase("audio")) {
layoutAudio.setVisibility(View.VISIBLE);
layoutImage.setVisibility(View.GONE);
seekBar.setFocusable(false);
txtAudioSendTime.setText(Utility.convertDateTime(sessionHistoryMesssage.getmSentTime()));
audioDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/A/Audio/";
File file = new File(Environment.getExternalStorageDirectory()
+ "/A/Audio/" + messageArrayList.get(position).getmMediaValue());
if (file.exists()) {
imgDownloadAudio.setVisibility(View.GONE);
playPauseImageView.setVisibility(View.VISIBLE);
playPauseImageView.setImageResource(R.drawable.play_icon);
} else {
imgDownloadAudio.setVisibility(View.VISIBLE);
playPauseImageView.setVisibility(View.GONE);
imgDownloadAudio.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
imgDownloadAudio.setVisibility(View.GONE);
Log.v("basepath", mBasePath);
new DownloadFile(mBasePath + messageArrayList.get(position).getmMediaPath() +
messageArrayList.get(position).getmMediaValue(),
audioDirectory + messageArrayList.get(position).getmMediaValue()
, imgDownloadAudio, progressAudioDownload).execute();
}
});
}
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
if (playposition == position) {
int seekBarPosition = seekBar.getProgress();
mPlayer.seekTo(seekBarPosition);
}
}
});
playPauseImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!mService.isPlaying()) {
playposition = position;
mService.playAudio(audioDirectory + messageArrayList.get(position).getmMediaValue());
notifyDataSetChanged();
} else {
if (playposition == position) {
playposition = -1;
mHandler.removeCallbacks(null);
mService.stopAudio();
notifyDataSetChanged();
} else {
playposition = position;
mService.playAudio(audioDirectory + messageArrayList.get(position).getmMediaValue());
notifyDataSetChanged();
}
}
}
});
} else if (messageArrayList.get(position).getmMediaType().equalsIgnoreCase("photo")) {
layoutImage.setVisibility(View.VISIBLE);
layoutAudio.setVisibility(View.GONE);
txtImageSendTime.setText(Utility.convertDateTime(messageArrayList.get(position).getmSentTime()));
imageDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/A/Image/";
Log.v("image path123", mBasePath + messageArrayList.get(position).getmMediaPath()
+ messageArrayList.get(position).getmMediaValue());
try {
File file = new File(Environment.getExternalStorageDirectory()
+ "/A/Image/" + messageArrayList.get(position).getmMediaValue());
if (!file.exists()) {
layoutdownloadImage.setVisibility(View.VISIBLE);
imageView.setVisibility(View.GONE);
} else {
layoutdownloadImage.setVisibility(View.GONE);
imageView.setVisibility(View.VISIBLE);
imageView.setImageBitmap(BitmapFactory.decodeFile(file.getAbsolutePath()));
}
layoutdownloadImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mSessionId = messageArrayList.get(position).getmSessionId();
imgDownloadImage.setVisibility(View.GONE);
new DownloadImage(mBasePath + messageArrayList.get(position).getmMediaPath()
+ sessionHistoryMesssage.getmMediaValue(),
sessionHistoryMesssage.getmMediaValue(),
imgDownloadImage, progressImageDownload
).execute();
}
});
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showImageDialog(position);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
if (sessionstartPosition == position) {
layoutSessionStart.setVisibility(View.VISIBLE);
layoutAudio.setVisibility(View.GONE);
layoutImage.setVisibility(View.GONE);
txtSessionStart.setText("Start session");
if (sessionHistoryMesssage.getmMediaType().equalsIgnoreCase("audio")) {
params = (RelativeLayout.LayoutParams) layoutSessionStart.getLayoutParams();
params.addRule(RelativeLayout.BELOW, R.id.layoutAudio);
} else if (sessionHistoryMesssage.getmMediaType().equalsIgnoreCase("photo")) {
params = (RelativeLayout.LayoutParams) layoutSessionStart.getLayoutParams();
params.addRule(RelativeLayout.BELOW, R.id.layoutImage);
} else {
}
if(!isSessionStarted) {
imageShareImageView.setVisibility(View.GONE);
recordAudioImageView.setVisibility(View.GONE);
imgEndSession.setVisibility(View.GONE);
isSessionStarted=true;
}
txtSessionStart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
retrofitRestAdapter = new RetrofitRestAdapter();
Map<String, String> sessionstartParams = new HashMap<String, String>();
sessionstartParams.put("session_id", sessionHistoryMesssage.getmSessionId());
final ProgressDialog progressDialog = new ProgressDialog(mContext);
progressDialog.setTitle("Please wait...");
progressDialog.show();
retrofitRestAdapter.sessionStart(sessionstartParams, new Callback<SessionHistoryResponse>() {
#Override
public void onResponse(Call<SessionHistoryResponse> call, Response<SessionHistoryResponse> response) {
Log.v("session start response", new Gson().toJson(response.body()));
progressDialog.dismiss();
txtSessionStart.setEnabled(false);
txtSessionStart.setClickable(false);
imageShareImageView.setVisibility(View.VISIBLE);
recordAudioImageView.setVisibility(View.VISIBLE);
imgEndSession.setVisibility(View.VISIBLE);
}
#Override
public void onFailure(Call<SessionHistoryResponse> call, Throwable t) {
t.printStackTrace();
progressDialog.dismiss();
imageShareImageView.setVisibility(View.GONE);
recordAudioImageView.setVisibility(View.GONE);
imgEndSession.setVisibility(View.GONE);
}
});
}
});
} else {
}
if (position == alreadystartPosition) {
layoutSessionStart.setClickable(false);
txtSessionStart.setClickable(false);
imageShareImageView.setVisibility(View.VISIBLE);
recordAudioImageView.setVisibility(View.VISIBLE);
imgEndSession.setVisibility(View.VISIBLE);
} else {
}
if (position == sessionendPosition) {
layoutSessionStart.setClickable(false);
txtSessionStart.setClickable(false);
// layoutSessionStart.setVisibility(View.VISIBLE);
txtSessionStart.setText("End session");
if (sessionHistoryMesssage.getmMediaType().equalsIgnoreCase("audio")) {
params = (RelativeLayout.LayoutParams) layoutSessionStart.getLayoutParams();
params.addRule(RelativeLayout.BELOW, R.id.layoutAudio);
} else if (sessionHistoryMesssage.getmMediaType().equalsIgnoreCase("photo")) {
params = (RelativeLayout.LayoutParams) layoutSessionStart.getLayoutParams();
params.addRule(RelativeLayout.BELOW, R.id.layoutImage);
} else {
}
imageShareImageView.setVisibility(View.GONE);
recordAudioImageView.setVisibility(View.GONE);
imgEndSession.setVisibility(View.GONE);
} else {
}
if (position == playposition) {
if (mBound) {
Log.v("service", "bound");
mHandler.removeCallbacks(null);
seekBar.setMax(mService.getrunningTime() / 1000);
Log.v("duration", mService.getrunningTime() + "");
playPauseImageView.setImageResource(R.drawable.stop_icon);
((PatientActivity) mContext).runOnUiThread(new Runnable() {
#Override
public void run() {
if (mService.isPlaying()) {
num = mService.getDuration();
seekBar.setProgress(num / 1000);
runningTimerTextView.setText(convertMilliToMinutes(num));
// vhItemHolder.seekBar.setFocusable(false);
mHandler.postDelayed(this, 50);
} else {
playposition = -1;
mHandler.removeCallbacks(null);
seekBar.setProgress(0);
seekBar.setFocusable(false);
runningTimerTextView.setText("00:00");
playPauseImageView.setImageResource(R.drawable.play_icon);
}
}
});
} else {
Log.v("service", "not bound");
}
} else {
mHandler.removeCallbacks(null);
playPauseImageView.setImageResource(R.drawable.play_icon);
runningTimerTextView.setText("00:00");
seekBar.setMax(0);
}
}
}
Service class
public class LocalService extends Service {
boolean mBound = false;
private final IBinder mBinder = new LocalBinder();
private int timer;
private MediaPlayer mediaPlayer = new MediaPlayer();
private boolean isStopped = true;
// Random number generator
/**
* Class used for the client Binder. Because we know this service always
* runs in the same process as its clients, we don't need to deal with IPC.
*/
public class LocalBinder extends Binder {
public LocalService getService() {
// Return this instance of LocalService so clients can call public methods
return LocalService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public int getrunningTime() {
return mediaPlayer.getDuration();
}
public int getDuration() {
// Log.v("player duration",timer+"");
if (mediaPlayer != null) {
if (!isStopped) {
Log.v("playing", (mediaPlayer.getCurrentPosition()) + "");
return mediaPlayer.getCurrentPosition();
} else {
// mediaPlayer.reset();
mHandler.removeCallbacks(null);
return 0;
}
} else {
Log.v("not playing", (mediaPlayer.getCurrentPosition()) + "");
mHandler.removeCallbacks(null);
return 0;
}
}
#Override
public void onCreate() {
super.onCreate();
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
isStopped = false;
//playAudio();
Log.v("max duration", timer + "");
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
//mediaPlayer.stop();
isStopped = true;
mediaPlayer.reset();
//mediaPlayer.release();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean isPlaying() {
if (mediaPlayer != null) {
try {
if (mediaPlayer.isPlaying()) {
return true;
} else {
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
} else {
return false;
}
}
public void playAudio(String path) {
Log.v("audio path",path);
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
}
mediaPlayer.reset();
try {
mediaPlayer.setDataSource(path);
mediaPlayer.prepare();
mediaPlayer.start();
} catch (IOException e) {
e.printStackTrace();
}
}
public void stopAudio() {
if (mediaPlayer != null) {
mediaPlayer.stop();
// mediaPlayer.reset();
isStopped = true;
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void unbindService(ServiceConnection conn) {
super.unbindService(conn);
mediaPlayer.reset();
mediaPlayer.release();
}
#Override
public void onDestroy() {
super.onDestroy();
mediaPlayer.reset();
mediaPlayer.release();
}
}

setHasStableIds(true); Add this in your adapter constructor and Override these two methodes in adapter.
#Override
public long getItemId(int pos) {
return pos;
}
#Override
public int getItemViewType(int pos) {
//return pos;
return Integer.parseInt(messageArrayList.get(position).getmSentBy());
}
It might help you...

Because you are calling notifyDataSetChanged() and it's updating the whole recyclerview whenever you do that. You better call notifyItemChanged(position) to update the certain item that you are supposed to update.
((PatientActivity) mContext).runOnUiThread(new Runnable() {
#Override
public void run() {
if (mService.isPlaying()) {
num = mService.getDuration();
seekBar.setProgress(num / 1000);
runningTimerTextView.setText(convertMilliToMinutes(num));
// vhItemHolder.seekBar.setFocusable(false);
mHandler.postDelayed(this, 50);
} else {
playposition = -1;
mHandler.removeCallbacks(null);
seekBar.setProgress(0);
seekBar.setFocusable(false);
runningTimerTextView.setText("00:00");
playPauseImageView.setImageResource(R.drawable.play_icon);
}
}
});
can you convert that into something like.
if (position == playposition) {
if (mBound) {
Log.v("service", "bound");
mHandler.removeCallbacks(null);
seekBar.setMax(mService.getrunningTime() / 1000);
Log.v("duration", mService.getrunningTime() + "");
playPauseImageView.setImageResource(R.drawable.stop_icon);
if (mService.isPlaying()) {
num = mService.getDuration();
seekBar.setProgress(num / 1000);
runningTimerTextView.setText(convertMilliToMinutes(num));
// vhItemHolder.seekBar.setFocusable(false);
notifyItemChanged(position);
} else {
playposition = -1;
mHandler.removeCallbacks(null);
seekBar.setProgress(0);
seekBar.setFocusable(false);
runningTimerTextView.setText("00:00");
playPauseImageView.setImageResource(R.drawable.play_icon);
notifyItemChanged(position);
}
}
}
Try to remove the whole usage of the runnable.

Related

RecycleView repeat action on one recycleview card on other

I am developing one quiz android application in which questions and their respective options and answer will be fetched from server and added to recycle view.
I have done coding of same and it is working except one problem that when i choose any option i turn its background green if it is right or i turn it to red if it is wrong but when i do same for any question same action is been transformed on other questions option in recycle view.
As i click on Option A
6th question from previous solved question have option A automatically selected
I am posting my Adapter and Fragment code for same.
Adapter code:-
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = LayoutInflater.from(context);
Log.e("I : ", "Creating " );
switch (viewType) {
case QUESTION:
View viewQuestion = inflater.inflate(R.layout.question_card, parent, false);
viewHolder = new QuestionFeed(viewQuestion);
break;
case LOADING:
View viewLoading = inflater.inflate(R.layout.item_progress, parent, false);
viewHolder = new LoadingVH(viewLoading);
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final PostRead result = postResults.get(position);
String catname = null;
try {
catname = dataBaseHelper.getCatName(result.getCat());
} catch (SQLException e) {
e.printStackTrace();
}
Log.e("Position: ", "" + position);
switch (getItemViewType(position)) {
case QUESTION:
final QuestionFeed textFeed = (QuestionFeed) holder;
textFeed.question.setText(result.getQuestion());
textFeed.optionA.setText(result.getA());
textFeed.optionB.setText(result.getB());
textFeed.optionC.setText(result.getC());
textFeed.optionD.setText(result.getD());
textFeed.answerView.setText(catname);
textFeed.time.setText("" + TimeAgo.getTimeAgo((10000000000000L - result.getTimestamp())));
textFeed.optionA_layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (result.getAnswer().equals("a")) {
Log.e("AAAAnswer- ", result.getAnswer());
textFeed.optionA_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else {
Log.e("Answer- ", result.getAnswer());
textFeed.optionA_layout.setBackgroundColor(context.getResources().getColor(R.color.wrong_answer));
if (result.getAnswer().equals("b")) {
textFeed.optionB_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else if (result.getAnswer().equals("c")) {
textFeed.optionC_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else if (result.getAnswer().equals("d")) {
textFeed.optionD_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
}
}
if (textFeed.descView.getVisibility() == View.GONE) {
textFeed.descView.setVisibility(View.VISIBLE);
}
}
});
textFeed.optionB_layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (result.getAnswer().equals("b")) {
Log.e("BBBAnswer- ", result.getAnswer());
textFeed.optionB_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else {
textFeed.optionB_layout.setBackgroundColor(context.getResources().getColor(R.color.wrong_answer));
if (result.getAnswer().equals("a")) {
textFeed.optionA_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else if (result.getAnswer().equals("c")) {
textFeed.optionC_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else if (result.getAnswer().equals("d")) {
textFeed.optionD_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
}
}
if (textFeed.descView.getVisibility() == View.GONE) {
textFeed.descView.setVisibility(View.VISIBLE);
}
}
});
textFeed.optionC_layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (result.getAnswer().equals("c")) {
Log.e("CCCAnswer- ", result.getAnswer());
textFeed.optionC_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else {
textFeed.optionC_layout.setBackgroundColor(context.getResources().getColor(R.color.wrong_answer));
if (result.getAnswer().equals("b")) {
textFeed.optionB_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else if (result.getAnswer().equals("a")) {
textFeed.optionA_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else if (result.getAnswer().equals("d")) {
textFeed.optionD_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
}
}
if (textFeed.descView.getVisibility() == View.GONE) {
textFeed.descView.setVisibility(View.VISIBLE);
}
}
});
textFeed.optionD_layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (result.getAnswer().equalsIgnoreCase("d")) {
Log.e("DDDAnswer- ", result.getAnswer());
textFeed.optionD_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else {
Log.e("DDDAnswer- ", result.getAnswer());
textFeed.optionD_layout.setBackgroundColor(context.getResources().getColor(R.color.wrong_answer));
if (result.getAnswer().equals("b")) {
textFeed.optionB_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else if (result.getAnswer().equals("c")) {
textFeed.optionC_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else if (result.getAnswer().equals("a")) {
textFeed.optionA_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
}
}
if (textFeed.descView.getVisibility() == View.GONE) {
textFeed.descView.setVisibility(View.VISIBLE);
}
}
});
break;
}
}
#Override
public int getItemCount() {
return postResults == null ? 0 : postResults.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return QUESTION;
}
public void add(PostRead r) {
postResults.add(r);
notifyItemInserted(postResults.size() - 1);
}
public void addAll(List<PostRead> moveResults) {
for (PostRead result : moveResults) {
add(result);
}
notifyDataSetChanged();
}
public void remove(PostRead r) {
int position = postResults.indexOf(r);
if (position > -1) {
postResults.remove(position);
notifyItemRemoved(position);
}
}
public void clear() {
isLoadingAdded = false;
while (getItemCount() > 0) {
remove(getItem(0));
}
}
public boolean isEmpty() {
return getItemCount() == 0;
}
public void addLoadingFooter() {
isLoadingAdded = true;
add(new PostRead());
}
public void removeLoadingFooter() {
isLoadingAdded = false;
int position = postResults.size() - 1;
PostRead result = getItem(position);
if (result != null) {
postResults.remove(position);
notifyItemRemoved(position);
}
}
public PostRead getItem(int position) {
return postResults.get(position);
}
protected class QuestionFeed extends RecyclerView.ViewHolder {
private ImageView back, share;
private MyTextView question;
private MyTextView optionA, optionB, optionC, optionD, answerView, time;
private LinearLayout optionA_layout, optionB_layout, optionC_layout, optionD_layout, errorLayout, descView;
private ProgressBar mProgress;
private Button btnRetry;
private TextView txtError;
private RelativeLayout mainLayout, backButton;
public QuestionFeed(View itemView) {
super(itemView);
back = (ImageView) itemView.findViewById(R.id.backView);
back = (ImageView) itemView.findViewById(R.id.share);
question = (MyTextView) itemView.findViewById(R.id.question);
optionA = (MyTextView) itemView.findViewById(R.id.optionA);
optionB = (MyTextView) itemView.findViewById(R.id.optionB);
optionC = (MyTextView) itemView.findViewById(R.id.optionC);
optionD = (MyTextView) itemView.findViewById(R.id.optionD);
answerView = (MyTextView) itemView.findViewById(R.id.subject);
time = (MyTextView) itemView.findViewById(R.id.time);
optionA_layout = (LinearLayout) itemView.findViewById(R.id.optionbuttonA);
optionB_layout = (LinearLayout) itemView.findViewById(R.id.optionbuttonB);
optionC_layout = (LinearLayout) itemView.findViewById(R.id.optionbuttonC);
optionD_layout = (LinearLayout) itemView.findViewById(R.id.optionbuttonD);
mProgress = (ProgressBar) itemView.findViewById(R.id.main_progress);
mainLayout = (RelativeLayout) itemView.findViewById(R.id.content_sign_up);
backButton = (RelativeLayout) itemView.findViewById(R.id.back_button);
descView = (LinearLayout) itemView.findViewById(R.id.desc);
errorLayout = (LinearLayout) itemView.findViewById(R.id.error_layout);
btnRetry = (Button) itemView.findViewById(R.id.error_btn_retry);
txtError = (TextView) itemView.findViewById(R.id.error_txt_cause);
}
}
Fragment Code
private void loadFirstPage() {
hideErrorView();
Query query = postRef.orderByChild("timestamp").startAt(firstTime).limitToFirst(14);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
final List<PostRead> allPosts = new ArrayList<>();
childCount = (int) dataSnapshot.getChildrenCount();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
// TODO: handle the post
Log.e("Online ", "" + firstTime);
PostRead catItems = postSnapshot.getValue(PostRead.class);
catItems.setPostkey(postSnapshot.getKey());
allPosts.add(catItems);
childCount--;
if (childCount == 0) {
firstStart = 0;
dataBaseHelper.updatePosts(allPosts);
hideErrorView();
progressBar.setVisibility(View.GONE);
adapter.addAll(allPosts);
isLoading = false;
if (allPosts.size() == 0) {
isLastPage = true;
} else adapter.addLoadingFooter();
}
firstTime = catItems.getTimestamp();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
That is because Views are recycled by RecyclerView and you are setting background color to different color manually.
The solution is to set default color for background of your textFeed in BindViewHolder as:
textFeed.optionA_layout.setBackgroundColor(context.getResources().getColor(R.color.default_color));
textFeed.optionB_layout.setBackgroundColor(context.getResources().getColor(R.color.default_color));
textFeed.optionC_layout.setBackgroundColor(context.getResources().getColor(R.color.default_color));
textFeed.optionD_layout.setBackgroundColor(context.getResources().getColor(R.color.default_color));

Imageview not on correct row after scrolling in Recyclerview

I have an app that displays my e-mail via microsoft graph api.
Everything but 1 things i working fine so far. When the list first loads in, all info is correctly displayed, but when i scroll down, then back up. The imageview of the attachement sits on the wrong rows. It just displays on rows without attachement. In the adapter i have an if clausule which says to only show the image in the row if the hasAttachement value is "true".. I really don't get why it is redrawin the image in the wrongs rows..
The method where i set the attachement is called:
setBijlage() in MessagesAdapter
EDIT: If i click the row in my app, that row displays correctly again (gains an icon if it has attachement, and deletes it if it doesn't)
MailActivity.java
public class MailActivity extends AppCompatActivityRest implements SwipeRefreshLayout.OnRefreshListener, MessagesAdapter.MessageAdapterListener {
private String currentFolder;
private String currentUser;
private List<Message> messages = new ArrayList<>();
private RecyclerView recyclerView;
private MessagesAdapter mAdapter;
private SwipeRefreshLayout swipeRefreshLayout;
private ActionModeCallback actionModeCallback;
private ActionMode actionMode;
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_mail);
super.onCreate(savedInstanceState);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
currentFolder = getString(R.string.inbox);
currentUser = getIntent().getStringExtra("USER_EMAIL");
setActionBarMail(currentFolder, currentUser);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);
swipeRefreshLayout.setOnRefreshListener(this);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
actionModeCallback = new ActionModeCallback();
// show loader and fetch messages
swipeRefreshLayout.post(
new Runnable() {
#Override
public void run() {
getAllMails(15);
}
}
);
}
#Override
public boolean onCreateOptionsMenu(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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_search) {
Toast.makeText(getApplicationContext(), "Search...", Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void processResponse(OutlookObjectCall outlookObjectCall, JSONObject response) {
switch (outlookObjectCall) {
case READUSER: {
System.out.println("reading user");
} break;
case READMAIL: {
messages.clear();
JSONObject list = response;
try {
JSONArray mails = list.getJSONArray("value");
Type listType = new TypeToken<List<Message>>() {
}.getType();
messages = new Gson().fromJson(String.valueOf(mails), listType);
for (Message message : messages) {
message.setColor(getRandomMaterialColor("400"));
}
System.out.println(messages.get(2).getFrom().getEmailAddress().getName());
mAdapter = new MessagesAdapter(this, messages, this);
recyclerView.setAdapter(mAdapter);
} catch (JSONException e) {
e.printStackTrace();
}
mAdapter.notifyDataSetChanged();
swipeRefreshLayout.setRefreshing(false);
}
break;
case SENDMAIL: {
System.out.println("Just send a mail." );
}
}
}
#Override
public void onRefresh() {
// swipe refresh is performed, fetch the messages again
getAllMails(15);
}
#Override
public void onIconClicked(int position) {
if (actionMode == null) {
actionMode = startSupportActionMode(actionModeCallback);
}
toggleSelection(position);
}
#Override
public void onIconImportantClicked(int position) {
// Star icon is clicked,
// mark the message as important
Message message = messages.get(position);
message.setImportance("normal");
messages.set(position, message);
mAdapter.notifyDataSetChanged();
}
#Override
public void onMessageRowClicked(int position) {
// verify whether action mode is enabled or not
// if enabled, change the row state to activated
if (mAdapter.getSelectedItemCount() > 0) {
enableActionMode(position);
} else {
// read the message which removes bold from the row
Message message = messages.get(position);
message.setIsRead("true");
messages.set(position, message);
mAdapter.notifyDataSetChanged();
Toast.makeText(getApplicationContext(), "Read: " + message.getBodyPreview(), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onRowLongClicked(int position) {
// long press is performed, enable action mode
enableActionMode(position);
}
private void enableActionMode(int position) {
if (actionMode == null) {
actionMode = startSupportActionMode(actionModeCallback);
}
toggleSelection(position);
}
private void toggleSelection(int position) {
mAdapter.toggleSelection(position);
int count = mAdapter.getSelectedItemCount();
if (count == 0) {
actionMode.finish();
} else {
actionMode.setTitle(String.valueOf(count));
actionMode.invalidate();
}
}
private class ActionModeCallback implements ActionMode.Callback {
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.menu_action_mode, menu);
// disable swipe refresh if action mode is enabled
swipeRefreshLayout.setEnabled(false);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.action_delete:
// delete all the selected messages
deleteMessages();
mode.finish();
return true;
default:
return false;
}
}
#Override
public void onDestroyActionMode(ActionMode mode) {
mAdapter.clearSelections();
swipeRefreshLayout.setEnabled(true);
actionMode = null;
recyclerView.post(new Runnable() {
#Override
public void run() {
mAdapter.resetAnimationIndex();
// mAdapter.notifyDataSetChanged();
}
});
}
}
// deleting the messages from recycler view
private void deleteMessages() {
mAdapter.resetAnimationIndex();
List<Integer> selectedItemPositions =
mAdapter.getSelectedItems();
for (int i = selectedItemPositions.size() - 1; i >= 0; i--) {
mAdapter.removeData(selectedItemPositions.get(i));
}
mAdapter.notifyDataSetChanged();
}
private void setActionBarMail(String title, String subtitle) {
getSupportActionBar().setTitle(title);
getSupportActionBar().setSubtitle(subtitle);
}
private void getAllMails(int aantalMails) {
swipeRefreshLayout.setRefreshing(true);
try {
new GraphAPI().getRequest(OutlookObjectCall.READMAIL, this, "/inbox/messages?$top=" + aantalMails);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
private int getRandomMaterialColor(String typeColor) {
int returnColor = Color.GRAY;
int arrayId = getResources().getIdentifier("mdcolor_" + typeColor, "array", getPackageName());
if (arrayId != 0) {
TypedArray colors = getResources().obtainTypedArray(arrayId);
int index = (int) (Math.random() * colors.length());
returnColor = colors.getColor(index, Color.GRAY);
colors.recycle();
}
return returnColor;
}
MessagesAdapter.java
public class MessagesAdapter extends RecyclerView.Adapter<MessagesAdapter.MyViewHolder> {
private Context mContext;
private List<Message> messages;
private MessageAdapterListener listener;
private SparseBooleanArray selectedItems;
// array used to perform multiple animation at once
private SparseBooleanArray animationItemsIndex;
private boolean reverseAllAnimations = false;
// index is used to animate only the selected row
// dirty fix, find a better solution
private static int currentSelectedIndex = -1;
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener {
public TextView from, subject, message, iconText, timestamp;
public ImageView iconImp, imgProfile, imgBijlage;
public LinearLayout messageContainer;
public RelativeLayout iconContainer, iconBack, iconFront;
public MyViewHolder(View view) {
super(view);
from = (TextView) view.findViewById(R.id.from);
subject = (TextView) view.findViewById(R.id.txt_primary);
message = (TextView) view.findViewById(R.id.txt_secondary);
iconText = (TextView) view.findViewById(R.id.icon_text);
timestamp = (TextView) view.findViewById(R.id.timestamp);
iconBack = (RelativeLayout) view.findViewById(R.id.icon_back);
iconFront = (RelativeLayout) view.findViewById(R.id.icon_front);
iconImp = (ImageView) view.findViewById(R.id.icon_star);
imgProfile = (ImageView) view.findViewById(R.id.icon_profile);
messageContainer = (LinearLayout) view.findViewById(R.id.message_container);
iconContainer = (RelativeLayout) view.findViewById(R.id.icon_container);
imgBijlage = (ImageView) view.findViewById(R.id.icon_attachement);
view.setOnLongClickListener(this);
}
#Override
public boolean onLongClick(View view) {
listener.onRowLongClicked(getAdapterPosition());
view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
return true;
}
}
public MessagesAdapter(Context mContext, List<Message> messages, MessageAdapterListener listener) {
this.mContext = mContext;
this.messages = messages;
this.listener = listener;
selectedItems = new SparseBooleanArray();
animationItemsIndex = new SparseBooleanArray();
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.message_list_row, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
Message message = messages.get(position);
// displaying text view data
holder.from.setText(message.getFrom().getEmailAddress().getName());
holder.subject.setText(message.getSubject());
holder.message.setText(message.getBodyPreview());
System.out.println("EMAIL: " + position + " HAS ATTACHEMENT: " + message.getHasAttachments());
setBijlage(message, holder);
try {
setDate(message, holder);
} catch (ParseException e) {
e.printStackTrace();
}
// displaying the first letter of From in icon text
holder.iconText.setText(message.getFrom().getEmailAddress().getName().substring(0, 1));
// change the row state to activated
holder.itemView.setActivated(selectedItems.get(position, false));
// change the font style depending on message read status
applyReadStatus(holder, message);
// handle message star
applyImportant(holder, message);
// handle icon animation
applyIconAnimation(holder, position);
// display profile image
applyProfilePicture(holder, message);
// apply click events
applyClickEvents(holder, position);
}
private void setDate(Message message, MyViewHolder holder) throws ParseException {
String stringDate = message.getReceivedDateTime();
String COMPARE_FORMAT = "yyyy/MM/dd";
String OUTPUT_FORMAT_NOT_TODAY = "dd MMM";
String JSON_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
SimpleDateFormat dateFormat = new SimpleDateFormat(COMPARE_FORMAT);
SimpleDateFormat formatter = new SimpleDateFormat(JSON_FORMAT);
SimpleDateFormat defaultFormat = new SimpleDateFormat(OUTPUT_FORMAT_NOT_TODAY);
//today date (check if today)
Date today = new Date();
String currentDate = dateFormat.format(today);
//hours (if today
Date date = formatter.parse(stringDate);
formatter.applyPattern(COMPARE_FORMAT);
String mailDate = formatter.format(date);
//dd/month (if not today)
boolean is24 = DateFormat.is24HourFormat(mContext);
if (mailDate.equals(currentDate)) {
if (is24) {
SimpleDateFormat outputFormat = new SimpleDateFormat("HH:mm");
holder.timestamp.setText(outputFormat.format(date));
} else {
SimpleDateFormat outputFormat = new SimpleDateFormat("hh:mm a");
holder.timestamp.setText(outputFormat.format(date));
}
} else {
holder.timestamp.setText(defaultFormat.format(date));
}
}
private void setBijlage(Message message, MyViewHolder holder){
//set bijlage
if (message.getHasAttachments().toLowerCase().equals("true")){
holder.imgBijlage.setImageResource(R.drawable.ic_bijlage);
}
}
private void applyClickEvents(MyViewHolder holder, final int position) {
holder.iconContainer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
listener.onIconClicked(position);
}
});
holder.iconImp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
listener.onIconImportantClicked(position);
}
});
holder.messageContainer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
listener.onMessageRowClicked(position);
}
});
holder.messageContainer.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
listener.onRowLongClicked(position);
view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
return true;
}
});
}
private void applyProfilePicture(MyViewHolder holder, Message message) {
holder.imgProfile.setImageResource(R.drawable.bg_circle);
holder.imgProfile.setColorFilter(message.getColor());
holder.iconText.setVisibility(View.VISIBLE);
}
private void applyIconAnimation(MyViewHolder holder, int position) {
if (selectedItems.get(position, false)) {
holder.iconFront.setVisibility(View.GONE);
resetIconYAxis(holder.iconBack);
holder.iconBack.setVisibility(View.VISIBLE);
holder.iconBack.setAlpha(1);
if (currentSelectedIndex == position) {
FlipAnimator.flipView(mContext, holder.iconBack, holder.iconFront, true);
resetCurrentIndex();
}
} else {
holder.iconBack.setVisibility(View.GONE);
resetIconYAxis(holder.iconFront);
holder.iconFront.setVisibility(View.VISIBLE);
holder.iconFront.setAlpha(1);
if ((reverseAllAnimations && animationItemsIndex.get(position, false)) || currentSelectedIndex == position) {
FlipAnimator.flipView(mContext, holder.iconBack, holder.iconFront, false);
resetCurrentIndex();
}
}
}
// As the views will be reused, sometimes the icon appears as
// flipped because older view is reused. Reset the Y-axis to 0
private void resetIconYAxis(View view) {
if (view.getRotationY() != 0) {
view.setRotationY(0);
}
}
public void resetAnimationIndex() {
reverseAllAnimations = false;
animationItemsIndex.clear();
}
#Override
public long getItemId(int position) {
return messages.get(position).getAutoId();
}
private void applyImportant(MyViewHolder holder, Message message) {
if (message.getImportance().toLowerCase().equals("high")) {
holder.iconImp.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.ic_star_black_24dp));
holder.iconImp.setColorFilter(ContextCompat.getColor(mContext, R.color.icon_tint_selected));
} else {
holder.iconImp.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.ic_star_border_black_24dp));
holder.iconImp.setColorFilter(ContextCompat.getColor(mContext, R.color.icon_tint_normal));
}
}
private void applyReadStatus(MyViewHolder holder, Message message) {
if (message.getIsRead().toLowerCase().equals("true")) {
holder.from.setTypeface(null, Typeface.NORMAL);
holder.subject.setTypeface(null, Typeface.NORMAL);
holder.from.setTextColor(ContextCompat.getColor(mContext, R.color.subject));
holder.subject.setTextColor(ContextCompat.getColor(mContext, R.color.message));
} else {
holder.from.setTypeface(null, Typeface.BOLD);
holder.subject.setTypeface(null, Typeface.BOLD);
holder.from.setTextColor(ContextCompat.getColor(mContext, R.color.from));
holder.subject.setTextColor(ContextCompat.getColor(mContext, R.color.subject));
}
}
#Override
public int getItemCount() {
return messages.size();
}
public void toggleSelection(int pos) {
currentSelectedIndex = pos;
if (selectedItems.get(pos, false)) {
selectedItems.delete(pos);
animationItemsIndex.delete(pos);
} else {
selectedItems.put(pos, true);
animationItemsIndex.put(pos, true);
}
notifyItemChanged(pos);
}
public void clearSelections() {
reverseAllAnimations = true;
selectedItems.clear();
notifyDataSetChanged();
}
public int getSelectedItemCount() {
return selectedItems.size();
}
public List<Integer> getSelectedItems() {
List<Integer> items =
new ArrayList<>(selectedItems.size());
for (int i = 0; i < selectedItems.size(); i++) {
items.add(selectedItems.keyAt(i));
}
return items;
}
public void removeData(int position) {
messages.remove(position);
resetCurrentIndex();
}
private void resetCurrentIndex() {
currentSelectedIndex = -1;
}
public interface MessageAdapterListener {
void onIconClicked(int position);
void onIconImportantClicked(int position);
void onMessageRowClicked(int position);
void onRowLongClicked(int position);
}
}
Change setBijlage to this..
private void setBijlage(Message message, MyViewHolder holder){
//set bijlage
if (message.getHasAttachments().toLowerCase().equals("true")){
holder.imgBijlage.setVisibility(View.VISIBLE);
holder.imgBijlage.setImageResource(R.drawable.ic_bijlage);
}else{
holder.imgBijlage.setVisibility(View.GONE);
}
}
That's occours because the recyclerView reuses the references of the rows and in your case, some rows doesnt have any reference in holder.imgBijlage, causing missbehavior.
To solve this, put holder.imgBijlage.setImageResource(R.drawable.ic_bijlage); inside onBindViewHolder and change setBijlage to:
if (message.getHasAttachments().toLowerCase().equals("true")){
holder.imgBijlage.setVisibility(View.VISIBLE);
}else {
holder.imgBijlage.setVisibility(View.INVISIBLE);
}
Your icon will be hidden when there is no attachement

callback in recyclerview affect all cells

I have a button in every cell of a RecyclerView that launches a download network call. The cell displays differently according to whether it's downloading, downloaded or finished.
my simplified code :
#Override public void onBindViewHolder(final CatalogViewHolder holder, int position) {
final DownloadStatusCallback statusCallback = new DownloadStatusCallback() {
#Override public void started() {
mainThreadHandler.post(new Runnable() {
#Override public void run() {
holder.itemView.setBackground(//color1
}
});
}
#Override public void finished() {
mainThreadHandler.post(new Runnable() {
#Override public void run() {
holder.itemView.setBackground(//color 2
}
});
}
#Override public void error(Exception e) {
mainThreadHandler.post(new Runnable() {
#Override public void run() {
holder.itemView.setBackground(//color 3
}
});
}
};
holder.button1.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View view) {
assyncCall(statusCallback);
}
});
}
The first time i clic on a cell, everything works fine. If I clic on the download button of another cell, both of them will update.
I understand that's due to recyclerview recycling cells, but I can't figure out how to do better.
Thanks !
my full adapter :
public class CatalogRecyclerAdapter extends RecyclerView.Adapter<CatalogViewHolder> {
public static final String TAG = "CatalogRecyclerAdapter";
private final LayoutInflater inflater;
private final DownloadCenter downloadCenter;
private final ListInterface.FlowController flowController;
private final ResourcesStringRepository resourcesStringRepository;
private final ImageManagerFactory imageManagerFactory;
private final Handler mainThreadHandler;
public CatalogRecyclerAdapter(LayoutInflater inflater, ListInterface.FlowController flowController,
DownloadCenter downloadCenter, ResourcesStringRepository resourcesStringRepository,
ImageManagerFactory imageManagerFactory, Handler mainThreadHandler) {
this.inflater = inflater;
this.flowController = flowController;
this.downloadCenter = downloadCenter;
this.resourcesStringRepository = resourcesStringRepository;
this.imageManagerFactory = imageManagerFactory;
this.mainThreadHandler = mainThreadHandler;
}
private static final int TITLE = 0;
private static final int USER = 2;
private static final int PROGRAM = 3;
private static final int COURSE = 4;
private static final int GROUP = 5;
private static final int MEDIA = 6;
private static final int ERROR = 7;
private static final int DEMO = 8;
//The list of all elements
private List<FilterableUser> users = new ArrayList<>();
private List<CatalogProgram> programs = new ArrayList<>();
private List<CatalogProgram> demos = new ArrayList<>();
private List<CatalogCourse> courses = new ArrayList<>();
private List<FilterableGroup> groups = new ArrayList<>();
private List<CatalogMedia> medias = new ArrayList<>();
//The list that will be displayed after filtering and research.
List<Object> displayedList = new ArrayList<>();
static final String TITLES[] = new String[10];
static {
Context ctx = M360Application.getContext();
TITLES[USER] = ctx.getString(R.string.users);
TITLES[PROGRAM] = ctx.getString(R.string.programs);
TITLES[COURSE] = ctx.getString(R.string.courses);
TITLES[GROUP] = ctx.getString(R.string.groups);
TITLES[MEDIA] = ctx.getString(R.string.documents);
TITLES[DEMO] = ctx.getString(R.string.programs_demo);
}
private String searchString;
#Override public int getItemViewType(int position) {
if (displayedList.get(position) instanceof String) {
return TITLE;
} else if (displayedList.get(position) instanceof FilterableUser) {
return USER;
} else if (displayedList.get(position) instanceof CatalogProgramDemo) {
return DEMO;
} else if (displayedList.get(position) instanceof CatalogProgram) {
return PROGRAM;
} else if (displayedList.get(position) instanceof CatalogCourse) {
return COURSE;
} else if (displayedList.get(position) instanceof FilterableGroup) {
return GROUP;
} else if (displayedList.get(position) instanceof CatalogMedia) {
return MEDIA;
} else if (displayedList.get(position) instanceof CatalogError) {
return ERROR;
} else {
throw new ClassCastException(
"this adapter's displayedList is corrupted" + displayedList.get(position).toString());
}
}
public void setData(List<Filterable> data, String searchedString) {
searchString = searchedString;
setData(data);
}
private void setData(List<Filterable> data) {
LogDev.i(TAG, "setting data size: " + data.size());
groups.clear();
users.clear();
programs.clear();
demos.clear();
courses.clear();
medias.clear();
for (Filterable element : data) {
if (element instanceof CatalogCourse) {
courses.add((CatalogCourse) element);
} else if (element instanceof FilterableUser) {
users.add((FilterableUser) element);
} else if (element instanceof CatalogProgramDemo) {
demos.add((CatalogProgramDemo) element);
} else if (element instanceof CatalogProgram) {
programs.add((CatalogProgram) element);
} else if (element instanceof FilterableGroup) {
groups.add((FilterableGroup) element);
} else if (element instanceof CatalogMedia) {
medias.add((CatalogMedia) element);
}
}
constructDataSet();
}
private void constructDataSet() {
displayedList.clear();
if (!demos.isEmpty()) {
displayedList.add(TITLES[DEMO]);
displayedList.addAll(demos);
}
if (!programs.isEmpty()) {
displayedList.add(TITLES[PROGRAM]);
displayedList.addAll(programs);
}
if (!courses.isEmpty()) {
displayedList.add(TITLES[COURSE]);
displayedList.addAll(courses);
}
if (!users.isEmpty()) {
displayedList.add(TITLES[USER]);
displayedList.addAll(users);
}
if (!groups.isEmpty()) {
displayedList.add(TITLES[GROUP]);
displayedList.addAll(groups);
}
if (!medias.isEmpty()) {
displayedList.add(TITLES[MEDIA]);
displayedList.addAll(medias);
}
if (displayedList.isEmpty()) {
displayedList.add(new CatalogError());
}
LogDev.w(TAG, "displayedList.size() : " + displayedList.size());
notifyDataSetChanged();
}
#Override public CatalogViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case TITLE:
return new TitleViewHolder(inflater.inflate(R.layout.item_list_title_catalog, parent, false));
case USER:
return new UserViewHolder(inflater.inflate(R.layout.widget_user_small, parent, false));
case PROGRAM:
case DEMO:
return new ProgramViewHolder(inflater.inflate(R.layout.widget_program_small, parent, false));
case COURSE:
return new CourseViewHolder(inflater.inflate(R.layout.widget_course_small, parent, false));
case GROUP:
return new GroupViewHolder(inflater.inflate(R.layout.widget_group_small, parent, false));
case MEDIA:
return new MediaViewHolder(inflater.inflate(R.layout.widget_media_small, parent, false));
case ERROR:
return new CatalogErrorViewHolder(inflater.inflate(R.layout.widget_noresult_small, parent, false));
default:
LogDev.e(TAG, "view type not supported");
return null;
}
}
#Override public void onBindViewHolder(CatalogViewHolder holder, int position) {
Object displayedObject = displayedList.get(position);
//holder.bind(displayedObject, errorDisplayInterface);
if (holder instanceof TitleViewHolder && displayedObject instanceof String) {
((TitleViewHolder) holder).tv.setText((String) displayedObject);
} else if (holder instanceof ProgramViewHolder && displayedObject instanceof CatalogProgram) {
bindProgramViewHolder((ProgramViewHolder) holder, (CatalogProgram) displayedObject);
} else if (holder instanceof CourseViewHolder && displayedObject instanceof CatalogCourse) {
bindCourseViewHolder((CourseViewHolder) holder, (CatalogCourse) displayedObject);
} else if (holder instanceof GroupViewHolder && displayedObject instanceof FilterableGroup) {
bindGroupViewHolder((GroupViewHolder) holder, (FilterableGroup) displayedObject);
} else if (holder instanceof UserViewHolder && displayedObject instanceof FilterableUser) {
bindUserViewHolder((UserViewHolder) holder, (FilterableUser) displayedObject);
} else if (holder instanceof MediaViewHolder && displayedObject instanceof CatalogMedia) {
bindMediaViewHolder((MediaViewHolder) holder, (CatalogMedia) displayedObject);
} else if (holder instanceof CatalogErrorViewHolder) {
//No binding with any data
} else {
throw new ClassCastException(displayedObject.toString());
}
//Highlight
if (searchString != null && !searchString.isEmpty())
{
TextViewHighlighter.highlight(holder, searchString);
}
}
private void bindCourseViewHolder(final CourseViewHolder courseViewHolder, final CatalogCourse course) {
courseViewHolder.name_textView.setText(course.name);
courseViewHolder.viewNb_textView.setText(course.views != null ? course.views.toString() : "0");
if (course.elementCount == null) {
courseViewHolder.counterLinear.setVisibility(View.GONE);
} else {
courseViewHolder.counterLinear.setVisibility(View.VISIBLE);
courseViewHolder.questionNb_textView.setText(
course.elementCount.questions != null ? course.elementCount.questions.toString() : "0");
courseViewHolder.mediaNb_textView.setText(
course.elementCount.medias != null ? course.elementCount.medias.toString() : "0");
courseViewHolder.sheetNb_textView.setText(
course.elementCount.sheets != null ? course.elementCount.sheets.toString() : "0");
}
imageManagerFactory.course(course.id).thumbnail(courseViewHolder.pic_imageView);
//new CourseImageManager(course.id).load(courseViewHolder.pic_imageView);
View.OnClickListener clickListener = new View.OnClickListener() {
#Override public void onClick(View view) {
flowController.routeToCourse(course.id);
}
};
courseViewHolder.container.setOnClickListener(clickListener);
if (course.canBeOffline) {
courseViewHolder.downloadBlock.setVisibility(View.VISIBLE);
DownloadState state = downloadCenter.getCourseStatus(course.id);
LogDev.i(TAG, "can be offline " + state.name());
if (state == DownloadState.DOWNLOADING) {
updateDownloadBlock(courseViewHolder, DownloadableStatus.DOWNLOADING);
}
if (state == DownloadState.TO_DOWNLOAD) {
updateDownloadBlock(courseViewHolder, DownloadableStatus.DOWNLOADABLE);
}
if (state == DownloadState.DOWNLOADED || state == DownloadState.DOWNLOADED_WITH_SHARED_MODE) {
updateDownloadBlock(courseViewHolder, DownloadableStatus.DOWNLOADED);
} else {
DownloadStatusCallback statusCallback = new DownloadStatusCallback() {
#Override public void started() {
LogDev.i(TAG, "started");
mainThreadHandler.post(new Runnable() {
#Override public void run() {
updateDownloadBlock(courseViewHolder, DownloadableStatus.DOWNLOADING);
}
});
}
#Override public void finished() {
mainThreadHandler.post(new Runnable() {
#Override public void run() {
updateDownloadBlock(courseViewHolder, DownloadableStatus.DOWNLOADED);
}
});
}
#Override public void error(Exception e) {
mainThreadHandler.post(new Runnable() {
#Override public void run() {
updateDownloadBlock(courseViewHolder, DownloadableStatus.ERROR);
}
});
}
};
downloadCenter.subscribe(course.id, statusCallback);
courseViewHolder.downloadBlock.setOnClickListener(new View.OnClickListener()
{
#Override public void onClick(View v) {
new Thread() {
#Override public void run() {
super.run();
try {
downloadCenter.downloadCourse(course.id, null);
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
});
}
} else {
LogDev.i(TAG, "can't be offline");
courseViewHolder.downloadBlock.setVisibility(View.INVISIBLE);
}
}
private void updateDownloadBlock(CourseViewHolder courseViewHolder, DownloadableStatus status) {
if (status == null) return;
courseViewHolder.downloadBlock.setVisibility(
status.equals(DownloadableStatus.NOT_DOWNLOADABLE) ? View.GONE : View.VISIBLE);
courseViewHolder.downloadImage.setVisibility(
status.equals(DownloadableStatus.DOWNLOADABLE) ? View.VISIBLE : View.GONE);
courseViewHolder.downloadProgress.setVisibility(
status.equals(DownloadableStatus.DOWNLOADING) ? View.VISIBLE : View.GONE);
courseViewHolder.downloadedImage.setVisibility(
status.equals(DownloadableStatus.DOWNLOADED) ? View.VISIBLE : View.GONE);
courseViewHolder.downloadErrImage.setVisibility(
status.equals(DownloadableStatus.ERROR) ? View.VISIBLE : View.GONE);
}
private enum DownloadableStatus {
NOT_DOWNLOADABLE, DOWNLOADABLE, DOWNLOADING, DOWNLOADED, ERROR
}
private void bindProgramViewHolder(ProgramViewHolder programViewHolder, final CatalogProgram program) {
imageManagerFactory.program(program.id).thumbnail(programViewHolder.pic_imageView);
//new ProgramImageManager(program.id).load(programViewHolder.pic_imageView);
View.OnClickListener onClickListener = new View.OnClickListener() {
#Override public void onClick(View view) {
flowController.routeToProgram(program.id);
}
};
programViewHolder.container.setOnClickListener(onClickListener);
programViewHolder.pic_imageView.setOnClickListener(onClickListener);
programViewHolder.title_textView.setText(program.name);
programViewHolder.viewCount_textView.setText(program.views != null ? program.views.toString() : "0");
}
private void bindUserViewHolder(UserViewHolder userViewHolder, final FilterableUser user) {
userViewHolder.name_textView.setText(user.name);
userViewHolder.job_textView.setText(user.description);
imageManagerFactory.user(user.id).thumbnail(userViewHolder.pic_imageView);
//new UserImageManager(user.id).loadProfilePic(userViewHolder.pic_imageView, NetworkUtils.isNetworkAvailable(),
// true);
View.OnClickListener onClickListener = new View.OnClickListener() {
#Override public void onClick(View view) {
flowController.routeToUser(user.id);
}
};
userViewHolder.pic_imageView.setOnClickListener(onClickListener);
userViewHolder.container.setOnClickListener(onClickListener);
}
private void bindMediaViewHolder(MediaViewHolder mediaViewHolder, final CatalogMedia media) {
imageManagerFactory.media(media.id, media.type, media.extention).symbolOnThumbnail(mediaViewHolder.complex);
//new MediaImageManager(media).load(mediaViewHolder.pic_imageView, NetworkUtils.isNetworkAvailable(), false);
mediaViewHolder.title_textView.setText(media.title);
mediaViewHolder.authorName_textView.setText(media.authorName);
View.OnClickListener onClickListener = new View.OnClickListener() {
#Override public void onClick(final View view) {
flowController.routeToDocument(media.id);
}
};
mediaViewHolder.complex.setOnClickListener(onClickListener);
mediaViewHolder.container.setOnClickListener(onClickListener);
}
private void bindGroupViewHolder(GroupViewHolder groupViewHolder, final FilterableGroup group) {
View.OnClickListener onClickListener = new View.OnClickListener() {
#Override public void onClick(View view) {
flowController.routeToGrouop(group.id);
}
};
groupViewHolder.pic_imageView.setOnClickListener(onClickListener);
groupViewHolder.container.setOnClickListener(onClickListener);
groupViewHolder.name_textView.setText(group.name);
String str = resourcesStringRepository.getQuantityString(R.plurals.catalog_group_stat_program,
group.nbProgramsRunning, group.nbProgramsRunning);
str += " - " + resourcesStringRepository.getQuantityString(R.plurals.catalog_group_stat_user, group.nbUser,
group.nbUser);
groupViewHolder.stats_textView.setText(str);
imageManagerFactory.group(group.id).thumbnail(groupViewHolder.pic_imageView);
//new GroupImageManager(group.id).load(groupViewHolder.pic_imageView, NetworkUtils.isNetworkAvailable(), true);
}
#Override public int getItemCount() {
return displayedList.size();
}
}
It is recycling the views.So while clicking the button you have to store its position and change views accordingly.
Maintain a position storing variable globally like this
private int itemClicked=-1;
While clicking the view store the position into itemclicked
holder.button1.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View view) {
itemclicked=position;
assyncCall(statusCallback);
}
});
Then while updating views check if the position is same like this
if(position==itemclicked){
//show download for clicked view
}else{
//show download stopped for other views
}
Solution
As Surender and Trickcy Solution suggested, I updated the presented data and then tell the adapter to update the cell accordingly :
DownloadStatusCallback statusCallback = new DownloadStatusCallback() {
#Override public void started() {
LogDev.i(TAG, "started");
course.downloadState = DownloadState.DOWNLOADING;
final int position = courseViewHolder.getAdapterPosition();
mainThreadHandler.post(new Runnable() {
#Override public void run() {
notifyItemChanged(position);
}
});
}
#Override public void finished() {
course.downloadState = DownloadState.DOWNLOADED;
final int position = courseViewHolder.getAdapterPosition();
mainThreadHandler.post(new Runnable() {
#Override public void run() {
notifyItemChanged(position);
}
});
}
#Override public void error(Exception e) {
course.downloadState = DownloadState.ERROR_WHILE_DOWNLOADING;
final int position = courseViewHolder.getAdapterPosition();
mainThreadHandler.post(new Runnable() {
#Override public void run() {
notifyItemChanged(position);
}
});
}
};

Recycler View showing wrong data when scrolled fast.Have Added Images For The Same

I have a RecycleView where i have three different views for cells. Data is shown perfectly when RView is loaded for the first time. As I start to scroll, it changes the view color. Tried different ways but not able to resolve it.
original view.
wrong view
public class TimelineRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int DATE_LAYOUT = 1;
private static final int EVEN_LAYOUT = 2;
private static final int ODD_LAYOUT = 3;
private List<TimeLineResponseDO.content> contents = new ArrayList<>();
Context context;
LayoutInflater layoutInflater;
private boolean isVisible = false;
private ConnectionDetector connectionDetector;
private ProgressDialog progressDialog;
private Fragment fragment1;
DateFormat inputFormat;
DateFormat outputFormat;
int counterOnCreate = 0;
int counterOnBind = 0;
public interface OpenSubmissionDetails{
void openSubmissionDetails(String submissionId);
}
public interface IGetTimeLineData {
void getTimeLineData(String date);
void loadSnackBar(String msg);
}
public ProgressDialog getProgressDialog(Context context){
if (progressDialog == null) {
progressDialog = new ProgressDialog(context);
progressDialog.setCancelable(false);
progressDialog.setMessage(context.getString(R.string.loading_message));
}
return progressDialog;
}
IGetTimeLineData getTimeLineData;
public IGetTimeLineData getGetTimeLineData() {
return getTimeLineData;
}
public void setGetTimeLineData(IGetTimeLineData getTimeLineData) {
this.getTimeLineData = getTimeLineData;
}
OpenSubmissionDetails openSubmissionDetails;
public OpenSubmissionDetails getOpenSubmissionDetails() {
return openSubmissionDetails;
}
public void setOpenSubmissionDetails(OpenSubmissionDetails openSubmissionDetails) {
this.openSubmissionDetails = openSubmissionDetails;
}
public TimelineRecyclerAdapter(List<TimeLineResponseDO.content> contents, Context context, Fragment fragment, IGetTimeLineData iGetTimeLineData) {
this.contents = contents;
this.context = context;
this.fragment1 = fragment;
this.getTimeLineData = iGetTimeLineData;
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
connectionDetector = new ConnectionDetector(context);
}
public class TimelineDateHolder extends RecyclerView.ViewHolder{
Button date;
public TimelineDateHolder(View convertView) {
super(convertView);
date = (Button) convertView.findViewById(R.id.date);
}
public void bindViews(TimeLineResponseDO.content response){
Date date1 = null;
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("DD-MM-yyyy");
long dateLong = System.currentTimeMillis();
String da = simpleDateFormat.format(dateLong);
Log.e(" Date is :- ", da);
if (response.getDate().equals(da)){
date.setText("Today");
}
else {
if (!TextUtils.isEmpty(response.getDate()))
date.setText(response.getDate());
}
}catch (Exception e){
e.printStackTrace();
if (!TextUtils.isEmpty(response.getDate()))
date.setText(response.getDate());
}
}
}
public class TimelineRecyclerEvenHolder extends RecyclerView.ViewHolder{
RelativeLayout evenContainer;
TextView subjectTypeEven, timingEven, subjectEven, locationEven, teacherEven, cancelTextEven;
Button submissionEven, notificationEven ,submissionEvenDetails ;
ImageView pointerEven, imgCancelBtnEven, imgDelayBtnEven, imgNotificationBtnEven;
View verticalLine;
public TimelineRecyclerEvenHolder(View convertView) {
super(convertView);
evenContainer = (RelativeLayout) convertView.findViewById(R.id.evenContainer);
subjectTypeEven = (TextView) convertView.findViewById(R.id.subjectTypeEven);
timingEven = (TextView) convertView.findViewById(R.id.timingEven);
subjectEven = (TextView) convertView.findViewById(R.id.subjectEven);
locationEven = (TextView) convertView.findViewById(R.id.locationEven);
teacherEven = (TextView) convertView.findViewById(R.id.teacherEven);
pointerEven = (ImageView) convertView.findViewById(R.id.circleEven);
submissionEven = (Button) convertView.findViewById(R.id.submissionEven);
submissionEvenDetails = (Button) convertView.findViewById(R.id.submissionEvenDetails);
imgCancelBtnEven = (ImageView) convertView.findViewById(R.id.cancelBtnEven);//#sp 29-09-2016 added
imgDelayBtnEven = (ImageView) convertView.findViewById(R.id.delayBtnEven);//#sp 30-09-2016 added
imgNotificationBtnEven = (ImageView) convertView.findViewById(R.id.notificationBtnEven);//#sp 30-09-2016 added
notificationEven = (Button) convertView.findViewById(R.id.notificationEven);//#sp 04-10-2016 added
cancelTextEven = (TextView) convertView.findViewById(R.id.cancelTextEven);
subjectTypeEven.setTypeface(NotifyApplication.getExoSemiBold(context));
timingEven.setTypeface(NotifyApplication.getExoSemiBold(context));
subjectEven.setTypeface(NotifyApplication.getExoSemiBold(context));
locationEven.setTypeface(NotifyApplication.getExoSemiBold(context));
teacherEven.setTypeface(NotifyApplication.getExoSemiBold(context));
cancelTextEven.setTypeface(NotifyApplication.getExoSemiBold(context));
}
public void bindViews(TimeLineResponseDO.content response, TimelineRecyclerEvenHolder holder){
holder.evenContainer.setVisibility(View.VISIBLE);
if (!TextUtils.isEmpty(response.getSubjectType())) {
holder.subjectTypeEven.setText(response.getSubjectType());
Log.d("Ifeven", "" + response.getSubjectType());
}
if (response.getLectureSubmission().equals(Enum.LectureSubmission.Submission.toString())) {
holder.subjectTypeEven.setText(Enum.LectureSubmission.Submission.toString());
Log.d("ElseIfeven", "" + response.getSubjectType());
}
Log.d("LectureSubmEven", "" + response.getLectureSubmission());
if (!TextUtils.isEmpty(response.getRoomNo()))
holder.locationEven.setText(response.getRoomNo());
if (!TextUtils.isEmpty(response.getSubject()))
holder.subjectEven.setText(response.getSubject());
if (Boolean.valueOf(StorageService.getInstance().getString("IS_STUDENT")))
{
if (!TextUtils.isEmpty(response.getTeacherAbbreviation()))
holder.teacherEven.setText(response.getTeacherAbbreviation());
}
else if (Boolean.valueOf(StorageService.getInstance().getString("IS_TEACHER")))
{
if (!TextUtils.isEmpty(response.getCourse()))
holder.teacherEven.setText(response.getCourse());
}
if (!TextUtils.isEmpty(response.getStartTime() + context.getString(R.string.timelineHypen) + response.getEndTime()))
holder.timingEven.setText(response.getStartTime() + context.getString(R.string.timelineHypen) + response.getEndTime());
holder.pointerEven.setBackgroundResource(R.drawable.timeline_pointer_left);
holder.timingEven.setCompoundDrawablesWithIntrinsicBounds(R.drawable.timeline_timing, 0, 0, 0);
Log.d("resp isSubmission", "" + response.isSubmission());
if (response.isSubmission()) {
holder.submissionEven.setVisibility(View.VISIBLE);
holder.submissionEven.setText(response.getSubmissionCount() + " Submission");
} else {
holder.submissionEven.setVisibility(View.GONE);
}
Log.d("resp Noti", "" + response.isNotiification());
if (response.isNotiification()) {
holder.notificationEven.setVisibility(View.VISIBLE);
} else {
holder.notificationEven.setVisibility(View.GONE);
}
if (response.getLectureSubmission().equals("Submission")) {
holder.submissionEvenDetails.setVisibility(View.VISIBLE);
} else {
holder.submissionEvenDetails.setVisibility(View.GONE);
}
if (response.isCancelled()) {
ChangeFontColorEven(holder);
}
if (response.getSubmissionStatus() != null) {
if (response.getSubmissionStatus().equals("No")) {
ChangeFontColorEven(holder);
}
}
if (response.isEvenLayout()) {
if (response.getLectureSubmission().equals("Submission")) {
holder.imgDelayBtnEven.setImageResource(R.drawable.pencil);
} else {
holder.imgDelayBtnEven.setImageResource(R.drawable.delay);
}
}
if (!TextUtils.isEmpty(response.getTrnLectureId())) {
submissionLoadId(response);
}
holder.notificationEven.setText(response.getNotificationCount() + " Notifications");
if (isVisible) {
if (!response.isDateContainer()) {
if (response.getLectureSubmission().equals("Submission") && !TextUtils.isEmpty(response.getLectureSubmission())) {
if (response.getSubmissionStatus().equals("No")) {
ShowHideEditLectureIconsEven(holder, View.GONE);
} else {
ShowHideEditLectureIconsEven(holder, View.VISIBLE);
}
} else {
if (response.isCancelled()) {
ShowHideEditLectureIconsEven(holder, View.GONE);
} else {
ShowHideEditLectureIconsEven(holder, View.VISIBLE);
}
}
}
}else {
ShowHideEditLectureIconsEven(holder, View.GONE);
}
}
}
public class TimelineRecyclerHolder extends RecyclerView.ViewHolder{
RelativeLayout oddContainer;
TextView subjectTypeOdd, timingOdd, subjectOdd, locationOdd, teacherOdd, tvCancelTextOdd;
Button submissionOdd, notificationOdd , submissionOddDetails;
ImageView pointerOdd, imgCancelBtnOdd, imgDelayBtnOdd, imgNotificationBtnOdd;
View verticalLine;
public TimelineRecyclerHolder(View convertView) {
super(convertView);
oddContainer = (RelativeLayout) convertView.findViewById(R.id.oddContainer);
subjectTypeOdd = (TextView) convertView.findViewById(R.id.subjectTypeOdd);
timingOdd = (TextView) convertView.findViewById(R.id.timingOdd);
subjectOdd = (TextView) convertView.findViewById(R.id.subjectOdd);
locationOdd = (TextView) convertView.findViewById(R.id.locationOdd);
teacherOdd = (TextView) convertView.findViewById(R.id.teacherOdd);
pointerOdd = (ImageView) convertView.findViewById(R.id.circleOdd);
submissionOdd = (Button) convertView.findViewById(R.id.submissionOdd);
submissionOddDetails = (Button) convertView.findViewById(R.id.submissionOddDetails);
imgCancelBtnOdd = (ImageView) convertView.findViewById(R.id.cancelBtnOdd);
imgDelayBtnOdd = (ImageView) convertView.findViewById(R.id.delayBtnOdd);
imgNotificationBtnOdd = (ImageView) convertView.findViewById(R.id.notificationBtnOdd);
notificationOdd = (Button) convertView.findViewById(R.id.notificationOdd);
tvCancelTextOdd = (TextView) convertView.findViewById(R.id.cancelTextOdd);
subjectTypeOdd.setTypeface(NotifyApplication.getExoSemiBold(context));
timingOdd.setTypeface(NotifyApplication.getExoSemiBold(context));
subjectOdd.setTypeface(NotifyApplication.getExoSemiBold(context));
locationOdd.setTypeface(NotifyApplication.getExoSemiBold(context));
teacherOdd.setTypeface(NotifyApplication.getExoSemiBold(context));
tvCancelTextOdd.setTypeface(NotifyApplication.getExoSemiBold(context));
}
public void bindViews(TimeLineResponseDO.content response, TimelineRecyclerHolder holder){
//holder.verticalLine.setVisibility(View.VISIBLE);
holder.oddContainer.setVisibility(View.VISIBLE);
if (!TextUtils.isEmpty(response.getSubjectType())) {
holder.subjectTypeOdd.setText(response.getSubjectType());
}
if (response.getLectureSubmission().equals(Enum.LectureSubmission.Submission.toString())) {
holder.subjectTypeOdd.setText(Enum.LectureSubmission.Submission.toString());
}
if (!TextUtils.isEmpty(response.getRoomNo()))
holder.locationOdd.setText(response.getRoomNo());
if (!TextUtils.isEmpty(response.getSubject()))
holder.subjectOdd.setText(response.getSubject());
if (Boolean.valueOf(StorageService.getInstance().getString("IS_STUDENT")))
{
if (!TextUtils.isEmpty(response.getTeacherAbbreviation()))
holder.teacherOdd.setText(response.getTeacherAbbreviation());
}
else if (Boolean.valueOf(StorageService.getInstance().getString("IS_TEACHER")))
{
if (!TextUtils.isEmpty(response.getCourse()))
holder.teacherOdd.setText(response.getCourse());
}
if (!TextUtils.isEmpty(response.getStartTime() + context.getString(R.string.timelineHypen) + response.getEndTime()))
holder.timingOdd.setText(response.getStartTime() + context.getString(R.string.timelineHypen) + response.getEndTime());
holder.pointerOdd.setBackgroundResource(R.drawable.timeline_pointer_right);
holder.timingOdd.setCompoundDrawablesWithIntrinsicBounds(R.drawable.timeline_timing, 0, 0, 0);
if (response.isSubmission()) {
holder.submissionOdd.setVisibility(View.VISIBLE);
holder.submissionOdd.setText(response.getSubmissionCount() + " Submission");
} else {
holder.submissionOdd.setVisibility(View.GONE);
}
if (response.isNotiification()) {
holder.notificationOdd.setVisibility(View.VISIBLE);
} else {
holder.notificationOdd.setVisibility(View.GONE);
}
if (response.getLectureSubmission().equals("Submission")) {
holder.submissionOddDetails.setVisibility(View.VISIBLE);
} else {
holder.submissionOddDetails.setVisibility(View.GONE);
}
if (response.isCancelled()) {
ChangeFontColor(holder, Enum.LayoutType.Odd);
}
if (response.getSubmissionStatus() != null) {
if (response.getSubmissionStatus().equals("No")) {
ChangeFontColor(holder, Enum.LayoutType.Odd);
}
}
if (response.getLectureSubmission().equals("Submission")) {
holder.imgDelayBtnOdd.setImageResource(R.drawable.pencil);
} else {
holder.imgDelayBtnOdd.setImageResource(R.drawable.delay);
}
if (!TextUtils.isEmpty(response.getTrnLectureId())) {
submissionLoadId(response);
}
holder.notificationOdd.setText(response.getNotificationCount() + " Notifications");
if (isVisible) {
if (!response.isDateContainer()) {
if (response.getLectureSubmission().equals("Submission") && !TextUtils.isEmpty(response.getLectureSubmission())) {
if (response.getSubmissionStatus().equals("No")) {
ShowHideEditLectureIcons(holder, View.GONE);
} else {
ShowHideEditLectureIcons(holder, View.VISIBLE);
}
} else {
if (response.isCancelled()) {
ShowHideEditLectureIcons(holder, View.GONE);
} else {
ShowHideEditLectureIcons(holder, View.VISIBLE);
}
}
}
}else {
ShowHideEditLectureIcons(holder, View.GONE);
}
}
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType){
case DATE_LAYOUT:
View convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.timeline_date_header, parent, false);
return new TimelineDateHolder(convertView);
case EVEN_LAYOUT:
View convertView1 = LayoutInflater.from(parent.getContext()).inflate(R.layout.timeline_even_layout_child, parent, false);
return new TimelineRecyclerEvenHolder(convertView1);
default:
View convertView2 = LayoutInflater.from(parent.getContext()).inflate(R.layout.timeline_odd_layout_child, parent, false);
return new TimelineRecyclerHolder(convertView2);
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final int itemType = getItemViewType(position);
TimeLineResponseDO.content content = contents.get(position);
switch (itemType){
case DATE_LAYOUT:
((TimelineDateHolder) holder).bindViews(content);
break;
case EVEN_LAYOUT:
((TimelineRecyclerEvenHolder) holder).bindViews(content, (TimelineRecyclerEvenHolder) holder);
break;
default:
((TimelineRecyclerHolder) holder).bindViews(content, (TimelineRecyclerHolder) holder);
break;
}
if (position == (contents.size() - 1)) {
if (connectionDetector.isConnectingToInternet()) {
getTimeLineData.getTimeLineData(content.getContentDate());
}
else {
getTimeLineData.loadSnackBar(context.getString(R.string.no_internet_connection_schedule));
}
}
}
#Override
public int getItemCount() {
return contents.size();
}
#Override
public int getItemViewType(int position) {
if (contents.get(position).isDateContainer()){
return DATE_LAYOUT;
}
else if (contents.get(position).isEvenLayout()){
return EVEN_LAYOUT;
}
else {
return ODD_LAYOUT;
}
}
private void ChangeFontColor(TimelineRecyclerHolder holder, Enum.LayoutType layoutType) {
switch (layoutType){
case Even:
break;
case Odd:
holder.subjectTypeOdd.setTextColor(context.getResources().getColor(android.R.color.holo_red_dark));
holder.timingOdd.setTextColor(context.getResources().getColor(android.R.color.holo_red_dark));
holder.pointerOdd.setBackgroundResource(R.drawable.timeline_pointer_right_red);
holder.subjectOdd.setTextColor(context.getResources().getColor(android.R.color.holo_red_dark));
holder.locationOdd.setVisibility(View.GONE);
holder.teacherOdd.setVisibility(View.GONE);
holder.tvCancelTextOdd.setVisibility(View.VISIBLE);
holder.tvCancelTextOdd.setTextColor(context.getResources().getColor(android.R.color.holo_red_dark));
holder.submissionOdd.setVisibility(View.GONE);
holder.submissionOddDetails.setVisibility(View.GONE);
break;
}
}
private void ChangeFontColorEven(TimelineRecyclerEvenHolder holder) {
holder.subjectTypeEven.setTextColor(context.getResources().getColor(android.R.color.holo_red_dark));
holder.timingEven.setTextColor(context.getResources().getColor(android.R.color.holo_red_dark));
holder.pointerEven.setBackgroundResource(R.drawable.timeline_pointer_left_red);
holder.subjectEven.setTextColor(context.getResources().getColor(android.R.color.holo_red_dark));
holder.locationEven.setVisibility(View.GONE);
holder.teacherEven.setVisibility(View.GONE);
holder.cancelTextEven.setVisibility(View.VISIBLE);
holder.cancelTextEven.setTextColor(context.getResources().getColor(android.R.color.holo_red_dark));
holder.submissionEven.setVisibility(View.GONE);
holder.submissionEvenDetails.setVisibility(View.GONE);
}
private void ShowHideEditLectureIcons(TimelineRecyclerHolder holder, int visibility) {
holder.imgCancelBtnOdd.setVisibility(visibility);
holder.imgDelayBtnOdd.setVisibility(visibility);
holder.imgNotificationBtnOdd.setVisibility(visibility);
}
private void ShowHideEditLectureIconsEven(TimelineRecyclerEvenHolder holder, int visibility) {
holder.imgCancelBtnEven.setVisibility(visibility);
holder.imgDelayBtnEven.setVisibility(visibility);
holder.imgNotificationBtnEven.setVisibility(visibility);
}
public void editEvent(boolean isVisible) {
this.isVisible = isVisible;
Log.d("Is Visible", String.valueOf(isVisible));
notifyDataSetChanged();
}
public void submission(final TimeLineResponseDO.content timeLineModel) {
final IGetSubmissionDetails iGetSubmissionDetails = new GetSubmissionDetailsBO();
iGetSubmissionDetails.getSubmissionByTrn(context, timeLineModel.getTrnLectureId(), new Response<ArrayList<String>>() {
#Override
public void onSuccess(ArrayList<String> callback) throws IOException {
StorageService.getInstance().putString("SubmissionId", callback.get(0));
FragmentManager fragmentManager = ((AppCompatActivity) context).getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
NoticeBoard noticeBoard = new NoticeBoard();
Bundle bundle = new Bundle();
bundle.putStringArrayList("submissionIds", callback);
bundle.putString("submissionId",callback.get(0));
bundle.putString("isFrom","submission_view");
noticeBoard.setArguments(bundle);
fragmentTransaction.replace(R.id.container, noticeBoard, NoticeBoard.class.getSimpleName());
fragmentTransaction.addToBackStack(NoticeBoard.class.getSimpleName());
fragmentTransaction.commit();
}
#Override
public void onError(Exception e, int i, String msg) {
Log.d("trnId error",e.toString());
}
});
}
public void submissionLoadId(final TimeLineResponseDO.content timeLineModel) {
final IGetSubmissionDetails iGetSubmissionDetails = new GetSubmissionDetailsBO();
iGetSubmissionDetails.getSubmissionByTrn(context, timeLineModel.getTrnLectureId(), new ResponseNew<ArrayList<String>>() {
#Override
public void onSuccess(ArrayList<String> callback, String id) throws IOException {
for (int i = 0; i < callback.size(); i++){
Log.e("trnId error", id + " " + callback.get(i));
if (AppConstant.initializeDbORReturn(context).isSubmissionIdExists(id, callback.get(i))){
Log.e("Already Exists :- ", id + " " + callback.get(i));
}
else {
AppConstant.initializeDbORReturn(context).insertSubmissionId(id, callback.get(i));
}
}
}
#Override
public void onError(Exception e, int i, String msg) {
}
});
}
private void localTimeLinedb(List<TimeLineResponseDO> callback, Context context) {
for (int i = 0; i < callback.size(); i++) {
TimeLineResponseDO timeLineResponseDO = callback.get(i);
for (int j = 0; j < timeLineResponseDO.getContentList().size(); j++) {
TimeLineResponseDO.content content = timeLineResponseDO.getContentList().get(j);
if (AppConstant.initializeDbORReturn(context).isTimeLineExits(timeLineResponseDO.getDate(),
content.getStaticLectureId(), content.getDate(),
content.getTrnLectureId(), content.getSlotId(), content.getSubject(),
content.getSubmissionId(), content.getLectureSubmission())) {
AppConstant.initializeDbORReturn(context).updateTimeLine(content, timeLineResponseDO.getDate());
} else {
AppConstant.initializeDbORReturn(context).insertIntoTimeLine(content, timeLineResponseDO.getDate());
}
}
}
}
public void getTimeLineData(String date, final Context context, final TimelineRecyclerHolder holder, final Enum.LayoutType even_odd, final Enum.EditLectureType editLectureType) {
inputFormat = new SimpleDateFormat("dd-mm-yyyy");
outputFormat = new SimpleDateFormat("yyyy-mm-dd");
ITimeLine timeLine = new TimeLineBO();
TimeLinePostDO timeLinePostDO = new TimeLinePostDO();
if (date == null) {
if (!TextUtils.isEmpty(StorageService.getInstance().getString("Running_Teacher_Id"))){
timeLinePostDO.setUserId(StorageService.getInstance().getString("Running_Teacher_Id"));
}
else {
timeLinePostDO.setUserId(StorageService.getInstance().getString("NEWUSER_ID"));
}
timeLinePostDO.setUserRoles(StorageService.getInstance().getString("USER_ROLES"));
} else {
if (!TextUtils.isEmpty(StorageService.getInstance().getString("Running_Teacher_Id"))){
timeLinePostDO.setUserId(StorageService.getInstance().getString("Running_Teacher_Id"));
}
else {
timeLinePostDO.setUserId(StorageService.getInstance().getString("NEWUSER_ID"));
}
timeLinePostDO.setUserRoles(StorageService.getInstance().getString("USER_ROLES"));
try {
timeLinePostDO.setDate(outputFormat.format(inputFormat.parse(date)));
} catch (ParseException e) {
e.printStackTrace();
}
}
timeLine.getTimeLineData(context, timeLinePostDO, new Response<List<TimeLineResponseDO>>() {
#Override
public void onSuccess(List<TimeLineResponseDO> callback) {
localTimeLinedb(callback, context);
getProgressDialog(context).dismiss();
switch (editLectureType){
case Cancel:
ChangeFontColor(holder, even_odd);
Toast.makeText(context, "Lecture Cancelled", Toast.LENGTH_SHORT).show();
ShowHideEditLectureIcons(holder, View.GONE);
break;
case Delay:
Toast.makeText(context, "Notification sent for delay", Toast.LENGTH_SHORT).show();
break;
case CreateNotification:
Toast.makeText(context, "Notification sent", Toast.LENGTH_SHORT).show();
break;
}
if (fragment1 instanceof TimeLineFragment){
((TimeLineFragment) fragment1).refreshList();
}
}
#Override
public void onError(Exception e, int i, String msg) {
}
});
}
}
Thanks in advance !
RecyclerViewAdapter recycles its views and thus the behavior is much expected.
When I read your code I saw that you've written if statements without else like :
if (!TextUtils.isEmpty(response.getRoomNo()))
holder.locationEven.setText(response.getRoomNo());
if (!TextUtils.isEmpty(response.getSubject()))
holder.subjectEven.setText(response.getSubject());
These will be reused if the view in the position before the newly loaded view doesn't fulfill that if statement.
Try adding else to your every if statement. By adding else I mean add something like
else {
holder.locationEven.setText("");
}
// OR
else {
holder.locationEven.setVisibility(View.GONE);
}

PullToRefreshAttacher.OnRefreshListener cannot be resolved to a type

am building an open source project, here is its link
http://slidese.github.io/slidese/2013/11/25/update_listview_item.html
I've imported all library projects which it is using into eclipse. All are fine except PullToRefresh library. it is giving me the error "PullToRefreshAttacher.OnRefreshListener cannot be resolved to a type" where fragment implements it
2nd error is at
mPullToRefreshAttacher.addRefreshableView(mListview, this);
it says "The method addRefreshableView(View, ViewDelegate) in the type PullToRefreshAttacher is not applicable for the arguments (ListView, ContentFragment)"
3rd error is at
#Override
public void onRefreshStarted(View view) {
Intent intent = new Intent(getActivity(), DownloaderService.class);
intent.putExtra(DownloaderService.EXTRA_USER_INITIATED, true);
getActivity().startService(intent);
}
It is asking me to remove override annotation. here is complete code of fragment.
public class ContentFragment extends Fragment implements PullToRefreshAttacher.OnRefreshListener {
private final String TAG = "ContentFragment";
public static final String CONTENT_MODE = "content_mode";
public static final int MODE_ADFREE = 0;
public static final int MODE_PREMIUM = 1;
private StartActivity mListener;
private PullToRefreshAttacher mPullToRefreshAttacher;
private UpdaterAsyncTask mUpdater;
private int mScrollState = OnScrollListener.SCROLL_STATE_IDLE;
ListView mListview;
Button mPlayButton;
ContentAdapter mAdapter;
int mMode;
Map<String, UpdateHolder> mUpdates = new HashMap<String, UpdateHolder>();
public ContentFragment() {
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (StartActivity) activity;
Log.d(TAG, "Attached podcast list fragment");
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must be the StartActivity");
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_content, null);
mListview = (ListView) view.findViewById(android.R.id.list);
mListview.setEmptyView(view.findViewById(R.id.empty_list_view));
mListview.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mListview.setMultiChoiceModeListener(new MultiChoiceModeListener() {
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.contextual_menu_content, menu);
return true;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (item.getItemId() == R.id.action_delete) {
SparseBooleanArray checked = mListview.getCheckedItemPositions();
Content[] params = new Content[checked.size()];
int index = 0;
int first = mListview.getFirstVisiblePosition();
int last = mListview.getLastVisiblePosition();
for (int i = 0; i < mListview.getCount(); i++) {
if (checked.get(i)) {
params[index++] = (Content)mListview.getItemAtPosition(i);
if (i >= first && i <= last) {
View view = mListview.getChildAt(i-first);
Animation animation = AnimationUtils.loadAnimation(getActivity(), android.R.anim.slide_out_right);
animation.setDuration(200);
//animation.setFillAfter(true);
animation.setStartOffset(100 * (index) );
view.startAnimation(animation);
}
}
}
new AsyncTask<Content, Void, Void>() {
#Override
protected Void doInBackground(Content... params) {
for (Content content : params) {
File file = Utils.getFilepath(content.getFilename());
file.delete();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
mAdapter.notifyDataSetChanged();
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
mode.finish();
return true;
}
return false;
}
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
}
});
mListview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view, int position, long id) {
Content content = mAdapter.getItem(position);
mListener.showContentDetails(content);
}
});
mListview.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
mScrollState = scrollState;
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
mPullToRefreshAttacher = ((StartActivity) getActivity()).getPullToRefreshAttacher();
mPullToRefreshAttacher.addRefreshableView(mListview, this);
mMode = getArguments().getInt(CONTENT_MODE);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public void onPause() {
super.onPause();
if (mUpdater != null)
mUpdater.stop();
}
#Override
public void onResume() {
super.onResume();
updateAdapter();
mUpdater = new UpdaterAsyncTask();
mUpdater.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void)null);
}
public void refresh() {
updateAdapter();
}
public void replaceCurrentlyPlayingContent() {
GlobalContext.INSTANCE.replaceCurrentlyPLayingContent(mAdapter.getObjects(), mListener.getCurrentTrack());
}
private void updateAdapter() {
Log.d(TAG, "updateAdapter");
//new FetchContentAsyncTask(mMode).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
final String mp3 = mListener.getSavedStateMp3();
final boolean isPlaying = mListener.getSavedStateIsPlaying();
final boolean isPaused = mListener.getSavedStateIsPaused();
List<Content> listOfContent = GlobalContext.INSTANCE.getCachedContent(mMode, mp3, isPlaying, isPaused);
mAdapter = new ContentAdapter(getActivity(), R.layout.list_item_card, listOfContent);
mListview.setAdapter(mAdapter);
}
#Override
public void onRefreshStarted(View view) {
Intent intent = new Intent(getActivity(), DownloaderService.class);
intent.putExtra(DownloaderService.EXTRA_USER_INITIATED, true);
getActivity().startService(intent);
}
private class UpdaterAsyncTask extends AsyncTask<Void, Void, Void> {
boolean isRunning = true;
public void stop() {
isRunning = false;
}
#Override
protected Void doInBackground(Void... params) {
while (isRunning) {
/*
Map<String, UpdateHolder> map = gatherMetadata();
publishProgress(map);
*/
updateCurrentAdapterContent();
publishProgress();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onProgressUpdate(Void... params) {
super.onProgressUpdate();
if (mScrollState == OnScrollListener.SCROLL_STATE_IDLE) {
// http://stackoverflow.com/questions/2123083/android-listview-refresh-single-row
int start = mListview.getFirstVisiblePosition();
for(int i = start, j = mListview.getLastVisiblePosition(); i<=j; i++) {
View view = mListview.getChildAt(i-start);
if (((Content)mListview.getItemAtPosition(i)).dirty) {
Log.v(TAG, "Content is dirty");
mListview.getAdapter().getView(i, view, mListview);
}
}
}
}
}
private void updateCurrentAdapterContent() {
List<Content> listOfContent = mAdapter.getObjects();
Map<String, UpdateHolder> map = new HashMap<String, UpdateHolder>();
DownloadManager.Query q = new DownloadManager.Query();
q.setFilterByStatus(DownloadManager.STATUS_PENDING | DownloadManager.STATUS_RUNNING);
try {
Cursor cursor = ContentDownloadManager.INSTANCE.query(q);
while (cursor.moveToNext()) {
//long id = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_ID));
String uri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_URI));
int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
int downloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
int total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
float progress = (float)downloaded/(float)total;
UpdateHolder holder = new UpdateHolder();
holder.progress = progress;
holder.status = status;
map.put(uri, holder);
}
cursor.close();
final Content currentContent = mListener.getCurrentTrack();
final boolean isPlaying = mListener.isPlaying();
final boolean isPaused = mListener.isPaused();
for (Content content : listOfContent) {
// First update any download progress we might have for this specific content item
UpdateHolder holder = map.get(content.mp3);
if (holder != null) {
if (content.downloadProgress != holder.progress) {
content.downloadProgress = holder.progress;
content.dirty = true;
}
if (content.downloadStatus != holder.status) {
content.downloadStatus = holder.status;
content.dirty = true;
}
}
else {
if (content.downloadProgress != 0f) {
content.downloadProgress = 0f;
content.dirty = true;
}
if (content.downloadStatus != -1) {
content.downloadStatus = -1;
content.dirty = true;
}
}
// Update with elapsed (to be done)
// File exists?
File file = Utils.getFilepath(content.getFilename());
if (content.exists != file.exists()) {
content.exists = file.exists();
content.dirty = true;
}
// Is this the currently playing content
if (currentContent != null && content.mp3.equals(currentContent.mp3)) {
if (content.isPlaying != isPlaying) {
content.isPlaying = isPlaying;
content.dirty = true;
}
if (content.isPaused != isPaused) {
content.isPaused = isPaused;
content.dirty = true;
}
}
else {
if (content.isPlaying != false) {
content.isPlaying = false;
content.dirty = true;
}
if (content.isPaused != false) {
content.isPaused = false;
content.dirty = true;
}
}
if (content.dirty) {
DatabaseManager.getInstance().createOrUpdateContent(content);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public class UpdateHolder {
public String mp3;
public int status;
public boolean played;
public float progress;
public boolean exists = false;
public boolean isPlaying = false;
public boolean isPaused = false;
//public int elapsed;
//public int duration;
}
}
I couldn't find the issue in it. I'm stuck here for last 40 hours. Please help. Thank you!
Maybe you are using old version of the library. I found that PullToRefreshAttacher doesn't contain OnRefreshListener. (https://github.com/chrisbanes/ActionBar-PullToRefresh/blob/master/library/src/main/java/uk/co/senab/actionbarpulltorefresh/library/PullToRefreshAttacher.java)
Try to import uk.co.senab.actionbarpulltorefresh.library.listeners.OnRefreshListener; and use it instead of PullToRefreshAttacher.OnRefreshListener.

Categories

Resources