I have a set of banner images that can slide when user slide it and touching image will redirect to some website..
I want to add auto scroll to the banner images, but I am not too sure how to do it, can anyone help me take a look at below code?
public class MyAdapter extends InfinitePagerAdapter {
BannerPagerAdapter pagerAdapter;
AutoScrollViewPager viewPager;
public static ArrayList<HashMap<String,String>> bannerAry = new ArrayList<HashMap<String,String>>();
public void onCreate(Bundle savedInstanceState) {
// Home header banner
LayoutInflater inflater = getLayoutInflater();
header = inflater.inflate(R.layout.home_banner, null);
if (homeBanner.equalsIgnoreCase("enable") && bannerAry.size() > 0){
gridView.addHeaderView(header);
}
viewPager = (AutoScrollViewPager) header.findViewById(R.id.view_pager);
pageIndicator = (LinePageIndicator) header.findViewById(R.id.indicator);
display = this.getWindowManager().getDefaultDisplay();
float scale = (float) display.getWidth() / Constants.HOME_BANNER_WIDTH;
int newHeight = (int) Math.round(Constants.HOME_BANNER_HEIGHT * scale);
viewPager.getLayoutParams().height = newHeight;
pagerAdapter = new BannerPagerAdapter(this, bannerAry);
viewPager.setAdapter(pagerAdapter);
pageIndicator.setViewPager(viewPager);
viewPager.addOnPageChangeListener(mOnPageChangeListener);
class BannerPagerAdapter extends PagerAdapter {
Context context;
LayoutInflater inflater;
ArrayList<HashMap<String,String>> data;
public BannerPagerAdapter(Context act, ArrayList<HashMap<String,String>> newary) {
this.data = newary;
this.context = act;
}
public int getCount() {
return data.size();
}
public Object instantiateItem(ViewGroup collection, final int position) {
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.banner_image,
collection, false);
ImageView image = (ImageView) itemView.findViewById(R.id.image);
String img = data.get(position).get("image");
Log.v("banner img", "img="+img);
if (!img.equals("")){
Picasso.with(FragmentMainActivity.this).load(img).into(image);
}
image.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (Patterns.WEB_URL.matcher(data.get(position).get("url")).matches()) {
Intent b = new Intent(Intent.ACTION_VIEW, Uri.parse(data.get(position).get("url")));
startActivity(b);
} else {
Toast.makeText(FragmentMainActivity.this, getString(R.string.url_invalid), Toast.LENGTH_SHORT).show();
}
}
});
((ViewPager) collection).addView(itemView, 0);
return itemView;
}
#Override
public void destroyItem(View arg0, int arg1, Object arg2) {
((ViewPager) arg0).removeView((View) arg2);
}
#Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == ((View) arg1);
}
#Override
public Parcelable saveState() {
return null;
}
}
ViewPager.OnPageChangeListener mOnPageChangeListener = new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrollStateChanged(int state) {
enableDisableSwipeRefresh( state == ViewPager.SCROLL_STATE_IDLE );
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageSelected(int position) {
}
};
private void enableDisableSwipeRefresh(boolean enabled){
if (enabled) {
swipeLayout.setEnabled(true);
} else {
swipeLayout.setEnabled(false);
}
}
You can do this by using a TimerTask where you can schedule scroll events with some duration gap, you need to call this method after you have initialized the viewPager and pagerAdapter, here's the code:
private void startAutoScrolling() {
stopAutoScrolling();
TimerTask task = new TimerTask() {
#Override
public void run() {
if(activityContext!=null)
activityContext.runOnUiThread(new Runnable() {
#Override
public void run() {
int position = (viewPager.getCurrentItem() + 1) % pagerAdapter.getCount();
viewPager.setCurrentItem(position);
}
});
}
};
timer = new Timer();
timer.scheduleAtFixedRate(task, 3000, 3000);
}
here stopAutoScrolling() method it to make sure that you stop the previous running TimerTask for auto scroll which may be the case if the user returns to app after pressing the home button or taking a call.
public void stopAutoScrolling() {
Log.i(TAG, "stop auto scroll of viewpager");
if (timer != null)
timer.cancel();
}
Related
I have 2 recycler views that have cards.They basically look the same have the same number of cards and everthing. The first one is for like viewing and other stuff and the second one is only for deleting cards. OnlongClicking a card in the first recycler view triggers the opening of the second recycler view. I wanted to add transitions in between them like what keep notes has done when a card is long clicked. Both the recycler view use the same adapter. I have set what the adapter should do based on passing context to the adapter. enter image description here this is my 1st layout having the 1st recycler view.enter image description here this is the 2nd layout having the second recycler view.I want like a seamless transition for the tool bar again just like what Google keeps has done.A simple solution would be preferred as I am very new to this stuff.
Here is the java code for the adapter.
public class Task_recycle_view_adapter extends RecyclerView.Adapter<Task_recycle_view_adapter.ViewHolder>{
private List<struct_task> task_list= new ArrayList<>();
private ArrayList<String> isSelected=new ArrayList<String>();
protected Context context1;
protected Context context2;
private String labelName;
private String taskName;
private ConstraintLayout label_menu_avatar;
public Task_recycle_view_adapter(Context context1,Context context2)
{
this.context1=context1;
this.context2=context2;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {//parent is the parent of the recycle view it is taken as an arg to use it to attach the every view to the parent view
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_task,parent,false);//to inflate a layout
ViewHolder holder= new ViewHolder(view);
return holder;
}
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.taskname.setText(task_list.get(position).getTask_name());
holder.taskid.setText(String.valueOf(task_list.get(position).getTask_id()));
if(context2==null && context1!=null) {
String taskName=task_list.get(position).getTask_name();
Long taskid=task_list.get(position).getTask_id();
String duedate=task_list.get(position).getDue_date();
holder.parent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DataBaseHelper dataBaseHelper = new DataBaseHelper(context1);
ArrayList<SubTaskModel> subtask_list=(ArrayList<SubTaskModel>) dataBaseHelper.getAllSubTasksFor(labelName, Long.parseLong(holder.taskid.getText().toString()));
Intent intent1 =new Intent(context1,ViewTaskActivity.class);
intent1.putExtra("label_name",labelName);
intent1.putExtra("task_id",taskid);
intent1.putExtra("task_name",taskName);
intent1.putExtra("due_date",duedate);
intent1.putParcelableArrayListExtra("subtask_list", (ArrayList<? extends Parcelable>) subtask_list);
context1.startActivity(intent1);
}
});
holder.parent.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
Intent intent2 = new Intent(context1, Delete_page_Activity.class);
intent2.putParcelableArrayListExtra("task_list", (ArrayList<? extends Parcelable>) task_list);
intent2.putExtra("label_name",labelName);
intent2.putExtra("selected_task",taskName);
Pair[] pairs = new Pair[1];
pairs[0]= new Pair<View,String>(label_menu_avatar,"transition1");
ActivityOptions options= ActivityOptions.makeSceneTransitionAnimation((Activity) context1,pairs);
context1.startActivity(intent2,options.toBundle());
return true;
}
});
}
if(context2!=null && context1==null)
{
if(taskName.equals(task_list.get(position).getTask_name()))
{
holder.active=1;
isSelected.add(holder.taskid.getText().toString());
holder.parent.findViewById(R.id.layout_for_every_task).setBackgroundResource(R.drawable.background_for_task_card);
}
holder.parent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(holder.active==0) {
isSelected.add(holder.taskid.getText().toString());
v.findViewById(R.id.layout_for_every_task).setBackgroundResource(R.drawable.background_for_task_card);
holder.active=1;
}
else {
isSelected.remove(holder.taskid.getText().toString());
v.findViewById(R.id.layout_for_every_task).setBackgroundResource(R.drawable.background_for_task_card_transparent);
holder.active=0;
}
}
});
}
// subtasks 1 to 5
if(task_list.get(position).getSubtask1()!=null)
holder.subtask1.setText(task_list.get(position).getSubtask1());
else
holder.subtask1.setVisibility(View.GONE);
if(task_list.get(position).getSubtask2()!=null)
holder.subtask2.setText(task_list.get(position).getSubtask2());
else
holder.subtask2.setVisibility(View.GONE);
if(task_list.get(position).getSubtask3()!=null)
holder.subtask3.setText(task_list.get(position).getSubtask3());
else
holder.subtask3.setVisibility(View.GONE);
if(task_list.get(position).getSubtask4()!=null)
holder.subtask4.setText(task_list.get(position).getSubtask4());
else
holder.subtask4.setVisibility(View.GONE);
if(task_list.get(position).getSubtask5()!=null)
holder.subtask5.setText(task_list.get(position).getSubtask5());
else
holder.subtask5.setVisibility(View.GONE);
// due date
if(task_list.get(position).getDue_date()!=null)
holder.duedate.setText(task_list.get(position).getDue_date());
else
holder.duedate.setVisibility(View.GONE);
// progress
holder.progresscircle.setProgress(task_list.get(position).getProgress());
}
#Override
public int getItemCount() {
return task_list.size();
}
public void setTask_list(List<struct_task> task_list) {
this.task_list = task_list;//to refresh the data inside the recycler view
}
#Override
public int getItemViewType(int position) {
return position;
}
public String getLabelName() {
return labelName;
}
public void setLabelName(String labelName) {
this.labelName = labelName;
}
public ArrayList<String> getIsSelected() {
return isSelected;
}
public String getTaskName() {
return taskName;
}
public void setTaskName(String taskName) {
this.taskName = taskName;
}
public void setLabel_menu_avatar(ConstraintLayout label_menu_avatar) {
this.label_menu_avatar = label_menu_avatar;
}
public static class ViewHolder extends RecyclerView.ViewHolder{// holds the view for every item inside the recycle view
private TextView taskname,taskid,duedate,subtask1,subtask2,subtask3,subtask4,subtask5;
private CardView parent;
private ProgressBar progresscircle;
public void setActive(int active) {
this.active = active;
}
private int active;
public ViewHolder(#NonNull View itemView) {
super(itemView);
taskid=itemView.findViewById(R.id.task_id);
taskname = itemView.findViewById(R.id.task_name);
parent = itemView.findViewById(R.id.card_for_every_task);
duedate = itemView.findViewById(R.id.due_date);
progresscircle = itemView.findViewById(R.id.progress_circular);
subtask1 = itemView.findViewById(R.id.subtask_1);
subtask2 = itemView.findViewById(R.id.subtask_2);
subtask3 = itemView.findViewById(R.id.subtask_3);
subtask4 = itemView.findViewById(R.id.subtask_4);
subtask5 = itemView.findViewById(R.id.subtask_5);
active=0;
}
}
}
Here is the code for the 1st activity i.e the 1st image:
public class TaskPageActivity extends AppCompatActivity {
private RecyclerView task_rv;//task recycler view
private FloatingActionButton addTask;
private long tasksNum;
private String labelName;
private DataBaseHelper dataBaseHelper = new DataBaseHelper(this);
private Task_recycle_view_adapter adapter= new Task_recycle_view_adapter(this,null);
private List<struct_task> tasks;
private EditText searchBar;
private ConstraintLayout search_btn;
private ConstraintLayout calendar_btn;
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_task_title);
getWindow().getSharedElementExitTransition();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
search_btn= findViewById(R.id.search_btn);
calendar_btn=findViewById(R.id.calendar_btn);
search_btn.setClickable(true);
search_btn.setFocusable(true);
labelName = getIntent().getExtras().getString("832715");
TextView txtLabelName = findViewById(R.id.Label_name);
txtLabelName.setText(labelName);
task_rv = findViewById(R.id.Recycle_view_task);
addTask = findViewById(R.id.add_task);
searchBar= (SearchBar) findViewById(R.id.search_bar);
tasksNum = getTasksNum(labelName, dataBaseHelper, adapter); //displays all tasks and return number of tasks
ConstraintLayout.LayoutParams params= (ConstraintLayout.LayoutParams) searchBar.getLayoutParams();
addTask.setOnClickListener(view -> {
tasksNum = getTasksNum(labelName, dataBaseHelper, adapter);
Intent intent = new Intent(TaskPageActivity.this, AddTaskPageActivity.class);
intent.putExtra("labelName", labelName);
intent.putExtra("taskID", tasksNum);
startActivity(intent);
});
search_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(searchBar.getVisibility()==View.INVISIBLE) {
search_btn.setAlpha(.5f);
searchBar.setVisibility(View.VISIBLE);
searchBar.requestFocus();
imm.showSoftInput(searchBar,InputMethodManager.SHOW_IMPLICIT);
ConstraintLayout.LayoutParams params= (ConstraintLayout.LayoutParams) searchBar.getLayoutParams();
params.verticalBias = .55f;
searchBar.setLayoutParams(params);
searchBar.requestFocus();
}
else {
searchBar.setVisibility(View.INVISIBLE);
search_btn.setAlpha(1.0f);
}
}
});
searchBar.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus) {
ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) searchBar.getLayoutParams();
if(params.verticalBias==.9f) {
searchBar.requestFocus();
params.verticalBias = .55f;
searchBar.setLayoutParams(params);
}
searchBar.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if((event.getAction()==KeyEvent.ACTION_DOWN) && (keyCode==KeyEvent.KEYCODE_ENTER) && params.verticalBias==.55f)
{
ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) searchBar.getLayoutParams();
searchBar.requestFocus();
params.verticalBias = .9f;
searchBar.setLayoutParams(params);
searchBar.clearFocus();
imm.hideSoftInputFromWindow(searchBar.getWindowToken(),0);
}
return false;
}
});
}
}
});
searchBar.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
filter(s.toString());
}
});
AlertDialog alertDialog = new AlertDialog.Builder(TaskPageActivity.this).create();
calendar_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(calendar_btn.getAlpha()==1.0f) {
calendar_btn.setAlpha(.5f);
LayoutInflater inflater = getLayoutInflater();
View view1 = inflater.inflate(R.layout.dialog_calendar,null);
alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
alertDialog.setView(view1);
CalendarView mCalendarView= view1.findViewById(R.id.calendar);
mCalendarView.setMinDate(Calendar.getInstance().getTimeInMillis());
alertDialog.show();
}
}
});
alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
if(calendar_btn.getAlpha()==.5f)
calendar_btn.setAlpha(1.0f);
}
});
}
private void filter(String string) {
ArrayList<struct_task> filteredList = new ArrayList<>();
for(struct_task item: tasks)
{
if(item.getTask_name().contains(string) || item.getTask_name().contains(string.toUpperCase()))
{
filteredList.add(item);
}
}
if(filteredList.size()!=0) {
adapter.setTask_list(filteredList);
task_rv.setAdapter(adapter);
}
}
#Override
public void onBackPressed() {
if(searchBar.getText().toString().length()!=0) {
showAllTasks(labelName, dataBaseHelper, adapter);
searchBar.setText(null);
searchBar.setVisibility(View.INVISIBLE);
search_btn.setAlpha(1.0f);
}
else if(searchBar.getText().toString().length()==0)
{
super.onBackPressed();
}
}
#Override
protected void onResume() {
ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) searchBar.getLayoutParams();
showAllTasks(labelName, dataBaseHelper, adapter);
if(params.verticalBias==.54f) {
searchBar.requestFocus();
params.verticalBias = .9f;
searchBar.setLayoutParams(params);
searchBar.clearFocus();
}
if(searchBar.getText().toString().length()==0) {
showAllTasks(labelName, dataBaseHelper, adapter);
}
else {
filter(searchBar.getText().toString());
}
super.onResume();
}
private void showAllTasks(String labelName, DataBaseHelper dataBaseHelper, Task_recycle_view_adapter adapter) {
tasks = dataBaseHelper.getAllTasksFor(labelName);
adapter.setLabelName(labelName);
adapter.setTask_list(tasks);
task_rv.setAdapter(adapter);
task_rv.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL));
}
long getTasksNum(String labelName, DataBaseHelper dataBaseHelper, Task_recycle_view_adapter adapter) {
return dataBaseHelper.getLastTaskID(labelName)+1; //to determine ID of next task
}
#Override
protected void onUserLeaveHint() {
ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) searchBar.getLayoutParams();
params.verticalBias=.9f;
searchBar.setLayoutParams(params);
searchBar.setText(null);
searchBar.clearFocus();
super.onUserLeaveHint();
}
}
And finally for the 2nd activity which is triggered by longclicking any card
public class Delete_page_Activity extends AppCompatActivity {
private Task_recycle_view_adapter recycle_view_adapter = new Task_recycle_view_adapter(null,this);
private ArrayList<String> delete_list=new ArrayList<>();
private DataBaseHelper dataBaseHelper = new DataBaseHelper(this);
private String labelName=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_delete_page);
overridePendingTransition(0,0);
Toolbar toolbar=findViewById(R.id.toolbar_bar);
ImageView close_btn=findViewById(R.id.close_btn);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(null);
ArrayList<struct_task> task_list = getIntent().getParcelableArrayListExtra("task_list");
labelName=getIntent().getExtras().getString("label_name");
String task = getIntent().getExtras().getString("selected_task");
Log.e("test",labelName);
RecyclerView recyclerView = findViewById(R.id.delete_Recycler_View);
recycle_view_adapter.setTaskName(task);
recycle_view_adapter.setTask_list(task_list);
recyclerView.setAdapter(recycle_view_adapter);
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL));
close_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar_menu,menu);
return true;
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId())
{
case R.id.tool_bar_item1:
delete_list = recycle_view_adapter.getIsSelected();
if(delete_list.size()==0)
{
Toast toast1= new Toast(this);
toast1.setDuration(Toast.LENGTH_SHORT);
LayoutInflater inflater= (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view= inflater.inflate(R.layout.activity_toast_msg1,null);
view.setBackgroundResource(R.drawable.background_for_calendar);
toast1.setView(view);
toast1.show();
}
else {
for (int task = 0; task < delete_list.size(); task++) {
dataBaseHelper.deleteOneTask(labelName, Long.parseLong(delete_list.get(task)));
}
finish();
}
break;
case R.id.tool_bar_item2:
Boolean flag=dataBaseHelper.deleteAllCompletedTasks(labelName);
if(flag)
finish();
else
{
Toast toast2= new Toast(this);
toast2.setDuration(Toast.LENGTH_SHORT);
LayoutInflater inflater= (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view= inflater.inflate(R.layout.activity_toast_msg2,null);
view.setBackgroundResource(R.drawable.background_for_calendar);
toast2.setView(view);
toast2.show();
}
break;
}
return true;
}
}
I have added the code related to the scene transititon which is in the adapter.
here is a gif of the problem when i add a scene transition
enter image description here
As u can see there are 2 pauses when going from 1st to 2nd activity 1st pause being longer 2nd one shorter. And also a pause when exiting the 2nd activity which seems to have the same duration as the 2nd pause.
I have RecyclerView(CardStackView) With 60 items.
Now After finish All Items .. I have Blank Page .. I do not want to Show The blank Page if all items finished ... I want to Intent to Another Activity You can see The blank Page Here
when I implement CardStackListener I Added Those Method too Like This .I want to When All card Answered Intent To ResultActivity...Like This After 60th question I want InstedOf Blank Page Intent To ResultActivity
//Card Method
#Override
public void onCardDragging(Direction direction, float ratio) {
Log.d("CardStackView", "onCardDragging: d = " + direction.name() + ", r = " + ratio);
}
#Override
public void onCardSwiped(Direction direction) {
Log.d("CardStackView", "onCardSwiped: p = " + manager.getTopPosition() + ", d = " + direction);
if (manager.getTopPosition() == mbtiQuestAdapter.getItemCount() - 5) {
mbtiQuestAdapter.addQuestion(questions);
mbtiQuestAdapter.notifyDataSetChanged();
}
position++;
Intent intent = new Intent(MbtiQuestionActivity.this, ResultActivity.class);
intent.putExtra(RESULT, result);
Log.i(TAG, "onResultClick: " + result);
startActivity(intent);
}
#Override
public void onCardRewound() {
Log.d("CardStackView", "onCardRewound: " + manager.getTopPosition());
}
#Override
public void onCardCanceled() {
Log.d("CardStackView", "onCardCanceled:" + manager.getTopPosition());
}
Adapter.java
public class MbtiQuestAdapter extends RecyclerView.Adapter<MbtiQuestAdapter.MbtiQuestViewHolder> {
private List<Question> questionList;
private LayoutInflater layoutInflater;
private final OnItemClickListener listener;
private static final String TAG = "MbtiQuestAdapter";
public interface OnItemClickListener {
void onItemClick(int position, char value);
}
public MbtiQuestAdapter(List<Question> questionList, OnItemClickListener listener) {
this.questionList = questionList;
this.listener = listener;
}
#NonNull
#Override
public MbtiQuestViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if (layoutInflater == null) {
layoutInflater = LayoutInflater.from(parent.getContext());
}
MbtiItemRowBinding binding = DataBindingUtil.inflate(layoutInflater,
R.layout.mbti_item_row, parent, false);
return new MbtiQuestViewHolder(binding);
}
#Override
public void onBindViewHolder(#NonNull final MbtiQuestViewHolder holder, final int position) {
final Question question = questionList.get(position);
holder.binding.txtQuesNum.setText(String.valueOf(position + 1));
holder.binding.txtQuesTitle.setText(question.getQuestion());
holder.binding.firstQues.setText(question.getAnswers().get(0).getAnswer());
holder.binding.secondQues.setText(question.getAnswers().get(1).getAnswer());
holder.binding.firstQues.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(position, question.getAnswers().get(0).getValue());
}
});
holder.binding.secondQues.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(position, question.getAnswers().get(1).getValue());
}
});
holder.binding.setQuestion(question);
}
#Override
public int getItemCount() {
Log.i(TAG, " List Size : " + questionList.size());
return questionList.size();
}
class MbtiQuestViewHolder extends RecyclerView.ViewHolder {
private MbtiItemRowBinding binding;
MbtiQuestViewHolder(MbtiItemRowBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
public void addQuestion(List<Question> questions) {
this.questionList.addAll(questions);
}
}
SetUp CardStackView In Activity
//Swipe RecyclerView with CardStackView
cardStackView = binding.cardStackView;
manager = new CardStackLayoutManager(this);
mbtiQuestAdapter = new MbtiQuestAdapter(questions, this);
cardStackView.setLayoutManager(manager);
cardStackView.setAdapter(mbtiQuestAdapter);
I want to Say If The items Finished Do SomeThing (Show Dialog or etc.)
Thank Guys
Working Code
private CardStackView cardStackView;
private CardStackLayoutManager layoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//
layoutManager = new CardStackLayoutManager(getApplicationContext(), this);
cardStackView.setLayoutManager(layoutManager);
//
}
#Override
public void onCardSwiped(Direction direction) {
if (layoutManager.getTopPosition() == adapter.getItemCount()) {
// -------------------- last position reached, do something ---------------------
startActivity(new Intent(this, MainActivity.class));
}
}
You have CardStackLayoutManager. When card is swiped, callback comes in onCardSwiped.
Here you will get top position (position displayed on top), and total item count.
If top_position == total_item_count, then it is last position, now you can do anything.
Below is Output or same
Use position to check if you have arrived to last item. Inside onBindViewHolder method
if( position+ 1 == questionList.size()){
// you are at the last item
}
You ca try this by using scrollChangeListener like :
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
LinearLayoutManager layoutManager=LinearLayoutManager.class.cast(recyclerView.getLayoutManager());
int totalItemCount = layoutManager.getItemCount();
int lastVisible = layoutManager.findLastVisibleItemPosition();
boolean endHasBeenReached = lastVisible + 5 >= totalItemCount;
if (totalItemCount > 0 && endHasBeenReached) {
//you have reached to the bottom of your recycler view
}
}
});
Some code correction, it is better not to create listeners in onBindViewHolder() because it will be set each time this method called, better to set ones in ViewHolder
For example :
Override
public void onBindViewHolder(#NonNull final MbtiQuestViewHolder holder, final int position) {
holder.bind(questionList.get(position))
}
class MbtiQuestViewHolder extends RecyclerView.ViewHolder {
private MbtiItemRowBinding binding;
MbtiQuestViewHolder(MbtiItemRowBinding binding) {
super(binding.getRoot());
this.binding = binding;
binding.firstQues.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(getAdapterPosition(), questionList.get(getAdapterPosition()).getAnswers().get(0).getValue());
}
});
binding.secondQues.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(getAdapterPosition(), questionList.get(getAdapterPosition()).getAnswers().get(1).getValue());
}
});
}
public void bind(Question question){
binding.txtQuesNum.setText(String.valueOf(position + 1));
binding.txtQuesTitle.setText(question.getQuestion());
binding.firstQues.setText(question.getAnswers().get(0).getAnswer());
binding.secondQues.setText(question.getAnswers().get(1).getAnswer());
binding.setQuestion(question);
}
public void addQuestion(List<Question> questions) {
this.questionList.addAll(questions);
}
}
you could compare with CardStackLayoutManager.getTopPosition(), which should be the index position currently displayed. the CardStackView GitHub explains the methods which are available.
alternatively, just count the number of swipes:
int currentPosition = 0;
#Override
public void onCardSwiped(Direction direction) {
currentPosition++;
}
//define the layoutmanager
private CardStackLayoutManager manager;
//make CardStackListener in layout manger and u need to implement methods
manager = new CardStackLayoutManager(this, new CardStackListener() {
#Override
public void onCardDragging(Direction direction, float ratio) {
}
#Override
public void onCardSwiped(Direction direction) {
}
#Override
public void onCardRewound() {
}
#Override
public void onCardCanceled() {
}
#Override
public void onCardAppeared(View view, int position) {
//here if u print position you will find the position of your viewed item and this function will call when card viewed
}
#Override
public void onCardDisappeared(View view, int position) {
Log.d("onCardDisappeared: ", "" + position);
//here if u print position you will find the position of your Disappeared item and this function will call when card disappear
}
}
});
cardStackView.setLayoutManager(manager);
cardStackView.setAdapter(cardStackAdapter);
I want to get vertical scrolling (one item at a time) but can't find they way to implement viewpager on my code. can anyone help me in implementing view pager on my code. I tried using Fragment for getting vertical scroll but no luck. Any help will be appreciated. Thanks in advance.
Here is my code,
MainActivity -
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
seekBar = (SeekBar) findViewById(R.id.seekBar);
songAdapter = new SongAdapter(this, _songs);
recyclerView.setAdapter(songAdapter);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
linearLayoutManager.getOrientation());
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.addItemDecoration(dividerItemDecoration);
songAdapter.setOnItemClickListener(new SongAdapter.OnItemClickListener() {
#Override
public void onItemClick(final Button b, View view, final SongInfo obj, int position) {
if (b.getText().equals("Stop")) {
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer.release();
mediaPlayer = null;
b.setText("Play");
} else {
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(obj.getSongUrl());
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
seekBar.setProgress(0);
seekBar.setMax(mediaPlayer.getDuration());
Log.d("Prog", "run: " + mediaPlayer.getDuration());
}
});
b.setText("Stop");
} catch (Exception e) {
}
}
};
myHandler.postDelayed(runnable, 100);
}
}
});
checkUserPermission();
Thread t = new runThread();
t.start();
}
public class runThread extends Thread {
#Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d("Runwa", "run: " + 1);
if (mediaPlayer != null) {
seekBar.post(new Runnable() {
#Override
public void run() {
seekBar.setProgress(mediaPlayer.getCurrentPosition());
}
});
Log.d("Runwa", "run: " + mediaPlayer.getCurrentPosition());
}
}
}
}
private void checkUserPermission() {
if (Build.VERSION.SDK_INT >= 23) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 123);
return;
}
}
//getMp3Songs();
loadSongs();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case 123:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//getMp3Songs();
loadSongs();
} else {
Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show();
checkUserPermission();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
private void loadSongs() {
Uri uri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI;
// Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = MediaStore.Audio.Media.IS_MUSIC + "!=0";
Cursor cursor = getContentResolver().query(uri, null, selection, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
String name = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME));
String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
String url = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
Log.i("DATA111", url);
mediaMetadataRetrieve = new MediaMetadataRetriever();
mediaMetadataRetrieve.setDataSource(url);
art = mediaMetadataRetrieve.getEmbeddedPicture();
if (art != null) {
songImage = BitmapFactory.decodeByteArray(art, 0, art.length);
}
SongInfo s = new SongInfo(name, artist, url, songImage);
_songs.add(s);
} while (cursor.moveToNext());
}
cursor.close();
songAdapter = new SongAdapter(MainActivity.this, _songs);
}
}
}
SongAdapter -
private ArrayList<SongInfo> _songs = new ArrayList<SongInfo>();
private Context context;
private OnItemClickListener mOnItemClickListener;
public SongAdapter(Context context, ArrayList<SongInfo> songs) {
this.context = context;
this._songs = songs;
}
public interface OnItemClickListener {
void onItemClick(Button b, View view, SongInfo obj, int position);
}
public void setOnItemClickListener(final OnItemClickListener mItemClickListener) {
this.mOnItemClickListener = mItemClickListener;
}
#Override
public SongHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View myView = LayoutInflater.from(context).inflate(R.layout.row_songs, viewGroup, false);
return new SongHolder(myView);
}
#Override
public void onBindViewHolder(final SongHolder songHolder, final int i) {
final SongInfo s = _songs.get(i);
songHolder.tvSongName.setText(_songs.get(i).getSongname());
songHolder.tvSongArtist.setText(_songs.get(i).getArtistname());
songHolder.tvAlbum_art.setImageBitmap(_songs.get(i).getThaImage());
songHolder.btnAction.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mOnItemClickListener != null) {
mOnItemClickListener.onItemClick(songHolder.btnAction, v, s, i);
}
}
});
}
#Override
public int getItemCount() {
return _songs.size();
}
public class SongHolder extends RecyclerView.ViewHolder {
TextView tvSongName, tvSongArtist;
Button btnAction;
ImageView tvAlbum_art;
public SongHolder(View itemView) {
super(itemView);
tvSongName = (TextView) itemView.findViewById(R.id.tvSongName);
tvSongArtist = (TextView) itemView.findViewById(R.id.tvArtistName);
tvAlbum_art = (ImageView) itemView.findViewById(R.id.album_art);
btnAction = (Button) itemView.findViewById(R.id.button_action);
}
}
}
VerticalViewPager -
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
this(context, null);
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
#Override
public boolean canScrollHorizontally(int direction) {
return false;
}
#Override
public boolean canScrollVertically(int direction) {
return super.canScrollHorizontally(direction);
}
private void init() {
setPageTransformer(true, new VerticalPageTransformer());
setOverScrollMode(View.OVER_SCROLL_NEVER);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final boolean toIntercept = super.onInterceptTouchEvent(flipXY(ev));
flipXY(ev);
return toIntercept;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
final boolean toHandle = super.onTouchEvent(flipXY(ev));
flipXY(ev);
return toHandle;
}
private MotionEvent flipXY(MotionEvent ev) {
final float width = getWidth();
final float height = getHeight();
final float x = (ev.getY() / height) * width;
final float y = (ev.getX() / width) * height;
ev.setLocation(x, y);
return ev;
}
private static final class VerticalPageTransformer implements ViewPager.PageTransformer {
#Override
public void transformPage(View view, float position) {
final int pageWidth = view.getWidth();
final int pageHeight = view.getHeight();
if (position < -1) {
view.setAlpha(0);
} else if (position <= 1) {
view.setAlpha(1);
view.setTranslationX(pageWidth * -position);
float yPosition = position * pageHeight;
view.setTranslationY(yPosition);
} else {
view.setAlpha(0);
}
}
}
}
Start with this simple example:
1) MnnnnnActivity.class:----------
public class MnnnnnActivity extends AppCompatActivity {
private VerticalViewPager vp;
private MPagerAdapter mPagerAdapter;
private int lastPage = 0;
private List<String> songs = new ArrayList<String>();
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout5);
vp = (VerticalViewPager) findViewById(R.id.vp);
for(int i = 0 ; i<10 ; i++){
songs.add(i , "song " + i);
}
mPagerAdapter = new MPagerAdapter(getApplicationContext(), songs);
vp.setAdapter(mPagerAdapter);
vp.setOffscreenPageLimit(1);
vp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
if(lastPage > position){ //left
}else{ // right
}
lastPage = position;
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
}
2) MPagerAdapter.class:-----
public class MPagerAdapter extends PagerAdapter {
private Context mContext;
private List<String> songs = new ArrayList<String>();
public MPagerAdapter(Context context , List<String> songs) {
mContext = context;
this.songs = songs;
}
#Override
#NonNull
public Object instantiateItem(#NonNull final ViewGroup collection, final int position) {
LayoutInflater inflater = LayoutInflater.from(mContext);
View layout = (View) inflater.inflate(R.layout.layout_list, collection, false);
TextView tv = (TextView) layout.findViewById(R.id.tv_song);
tv.setText(songs.get(position));
Button b = (Button) layout.findViewById(R.id.b_song);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(mContext , "Play " + songs.get(position) , Toast.LENGTH_LONG).show();
}
});
collection.addView(layout);
return layout;
}
#Override
public void destroyItem(ViewGroup collection, int position, Object view) {
collection.removeView((View) view);
}
#Override
public int getCount() {
return songs.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#Override
public CharSequence getPageTitle(int position) {
return songs.get(position);
}
}
3) VerticalViewPager.class:-------
//https://stackoverflow.com/questions/13477820/android-vertical-viewpager
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
super(context);
init();
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
setPageTransformer(true, new VerticalPageTransformer());
setOverScrollMode(OVER_SCROLL_NEVER);
}
private MotionEvent swapXY(MotionEvent ev) {
float width = getWidth();
float height = getHeight();
float newX = (ev.getY() / height) * width;
float newY = (ev.getX() / width) * height;
ev.setLocation(newX, newY);
return ev;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
swapXY(ev);
//https://stackoverflow.com/questions/15365915/viewpager-nested-in-viewpager
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_UP:
this.getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_DOWN:
this.getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_MOVE:
this.getParent().requestDisallowInterceptTouchEvent(true);
break;
}
return intercepted;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapXY(ev));
}
}
4) VerticalPageTransformer.class:-----------
//https://stackoverflow.com/questions/13477820/android-vertical-viewpager
public class VerticalPageTransformer implements ViewPager.PageTransformer {
#Override
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
int pageHeight = view.getHeight();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 1) { // [-1,1]
view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(pageWidth * -position);
//set Y position to swipe in from top
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
5) layout5.xml:--------
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.admin.accessories.VerticalViewPager
android:id="#+id/vp"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.example.admin.accessories.VerticalViewPager>
</android.support.constraint.ConstraintLayout>
6) layout_list.xml:--------
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:text="SName"
android:layout_marginBottom="20dp"
android:id="#+id/tv_song"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Play"
android:id="#+id/b_song"/>
</LinearLayout>
7) Output:---------
Simple solution is try rotating viewpager and its child view
mViewPager.setRotation(90);
It will rotate view pager and it's child views as well. Now rotate child view again in opposite direction.
childView.setRotation(270);
My recyclerview is not updating correctly after the back button is
pressed.
The recyclerview works fine before the back button is pressed
The data is properly updated (seen in the log) but the recyclerview does not reflect the change
The purpose of the handler is to poll the database for a notification (working fine)
The notification toast is displayed everytime
I am not receiving any errors
If I can provide any other information to help do not hesitate to ask.
Main:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat_room);
recView = (RecyclerView) findViewById(R.id.recyclerViewMessages);
linearLayoutManager = new LinearLayoutManager(this) {};
linearLayoutManager.setReverseLayout(true);
recView.setLayoutManager(linearLayoutManager);
listData = (ArrayList) MessagingData.getMessageListData();
adapter = new RecyclerViewAdapterMessaging(listData, this);
recView.setAdapter(adapter);
adapter.setItemClickCallback(this);
final Handler h = new Handler();
final int delay = 2000; //milliseconds
h.postDelayed(new Runnable(){
public void run(){
Notify_Message_Async notify_message_async = new Notify_Message_Async(ctx);
notify_message_async.execute(NOTIFICATION, message_id);
System.out.println(global.getNotification());
if(global.getNotification()==1){
Toast.makeText(ctx, "Notified",
Toast.LENGTH_LONG).show();
try {
refresh_receive();
} catch (ExecutionException e) {
Toast.makeText(ctx, "catch",
Toast.LENGTH_LONG).show();
e.printStackTrace();
} catch (InterruptedException e) {
Toast.makeText(ctx, "catch",
Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
h.postDelayed(this, delay);
}
}, delay);
}
public void refresh_receive() throws ExecutionException, InterruptedException {
String method = "receive_message";
Receive_Live_Message_Async receive_live_message_async = new Receive_Live_Message_Async(this);
receive_live_message_async.execute(method, message_id).get();// Setup the message
adapter.setListData((ArrayList)MessagingData.getMessageListData());
adapter.notifyDataSetChanged();
global.setNotification(0);//reset notification
}
Adapter:
public class RecyclerViewAdapterMessaging extends RecyclerView.Adapter<RecyclerViewAdapterMessaging.Holder> {
private View v;
private List<List_Item_Messaging> listData;
private LayoutInflater inflater;
Global global = new Global();
private ItemClickCallback itemClickCallback;
Context context;
public interface ItemClickCallback {
void onItemClick(View v, int p);
void onSecondaryIconClick(int p);
}
public void setItemClickCallback(final ItemClickCallback itemClickCallback) {
this.itemClickCallback = itemClickCallback;
}
public RecyclerViewAdapterMessaging(List<List_Item_Messaging> listData, Context c) {
inflater = LayoutInflater.from(c);
context = c;
this.listData = listData;
}
#Override
public int getItemViewType(int position) {//0 for self... /1 for Other
List_Item_Messaging item = listData.get(position);
//ENSURE GLOBAL USERNAME NOT NULL
String other_username = item.getMessage_username();
if (other_username == null) {
((Activity) context).finish();
}
if (item.getMessage_username().trim().equals(global.getUserName())) {
System.out.println("The usernames are the same");
return 0;
} else {
System.out.println("The usernames are the NOT same");
return 1;
}
}
#Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case 0:
View view = inflater.inflate(R.layout.chat_thread, parent, false);// Self
v = view;
break;
case 1:
View view2 = inflater.inflate(R.layout.chat_thread_other, parent, false);// Not self
int width2 = global.getScreenWidth();
v = view2;
break;
}
return new Holder(v);
}
#Override
public void onBindViewHolder(Holder holder, int position) {
List_Item_Messaging item = listData.get(position);
holder.conversation.setText(item.getMessage_conversation());
}
public void setListData(ArrayList<List_Item_Messaging> exerciseList) {
this.listData.clear();
this.listData.addAll(exerciseList);
}
#Override
public int getItemCount() {
return listData.size();
}
class Holder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView thumbnail;
//ImageView secondaryIcon;
TextView conversation;
View message_container;
public Holder(View itemView) {
super(itemView);
conversation = (TextView) itemView.findViewById(R.id.conversation_textview);
message_container = itemView.findViewById(R.id.message_container);
message_container.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.message_container) {
itemClickCallback.onItemClick(v, getAdapterPosition());
} else {
itemClickCallback.onSecondaryIconClick(getAdapterPosition());
}
}
}
public void clearItems() {
listData.clear();
this.notifyDataSetChanged();
}
}
I have referenced the following to no solution:
notifyDataSetChanged not working on RecyclerView
smoothScrollToPosition after notifyDataSetChanged not working in android
adapter.notifyDataSetChange() not working after called from onResume()
change a little in your code
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat_room);
recView = (RecyclerView) findViewById(R.id.recyclerViewMessages);
linearLayoutManager = new LinearLayoutManager(this) {};
linearLayoutManager.setReverseLayout(true);
recView.setLayoutManager(linearLayoutManager);
// change here
if (listData != null)
listData.clear();
else listData = new <> ArrayList();
listData.addAdd((ArrayList)MessagingData.getMessageListData());
adapter = new RecyclerViewAdapterMessaging(listData, this);
recView.setAdapter(adapter);
adapter.setItemClickCallback(this);
final Handler h = new Handler();
final int delay = 2000; //milliseconds
then make a small change here
public void refresh_receive() throws ExecutionException, InterruptedException {
String method = "receive_message";
Receive_Live_Message_Async receive_live_message_async = new Receive_Live_Message_Async(this);
receive_live_message_async.execute(method, message_id).get();// Setup the message
// changing here
dataList.clear();
dataList.addAdd((ArrayList)MessagingData.getMessageListData())
adapter.setListData(dataList);
adapter.notifyDataSetChanged();
global.setNotification(0);//reset notification
}
another problem in your code, you are using receive_live_message_async AsyncTask
put your update code in onPostExecute
public class receive_live_message_async extends AsyncTask {
#Override
protected Object doInBackground(Object[] objects) {
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(Object o) {
// call your refresh_receive(); here
super.onPostExecute(o);
}
}
similarly when you are call receive_live_message_async.execute(); update your recyclerView in onPostExecute
#Override
protected void onPostExecute(Object o) {
dataList.clear();
dataList.addAll((ArrayList)MessagingData.getMessageListData());
adapter.notifyDataSetChanged();
super.onPostExecute(o);
}
Heres my activity:
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private List<GalleryItem> mGalleryItems;
GalleryAdapter adapter;
private boolean loading = true;
int pastVisiblesItems, visibleItemCount, totalItemCount;
LinearLayoutManager mLayoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.grid_view);
mGalleryItems = new ArrayList<>();
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
getItems("http://www.reddit.com/r/aww.json");
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 0) {
visibleItemCount = mLayoutManager.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition();
if (loading) {
if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
loading = false;
Log.v("...", "Last Item Wow !");
getItems("https://www.reddit.com/r/aww.json?after=t3_40x6ke");
}
}
}
}
});
adapter = new GalleryAdapter(mGalleryItems, this);
mRecyclerView.setAdapter(adapter);
}
#Override
public void onDestroy(){
super.onDestroy();
}
public void getItems(String url){
OkHttpClient client = new OkHttpClient();
File cacheDirectory = new File(MainActivity.this.getCacheDir(), "http");
int cacheSize = 10 * 1024 * 1024;
Cache cache = new Cache(cacheDirectory, cacheSize);
client.setCache(cache);
Request request = new Request.Builder()
.url(url)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
#Override
public void onFailure(Request request, IOException e) {
}
#Override
public void onResponse(Response response) throws IOException {
final String json = response.body().string();
if (response.isSuccessful()) {
try {
mGalleryItems.addAll(parseItems(json));
} catch (JSONException e) {
e.printStackTrace();
Log.i("BEHS", e.getMessage());
}
runOnUiThread(new Runnable() {
#Override
public void run() {
adapter.notifyDataSetChanged();
}
});
}
}
});
}
private List<GalleryItem> parseItems(String json) throws JSONException {
JSONObject jsonMovie = new JSONObject(json);
JSONObject firstData = jsonMovie.getJSONObject("data");
JSONArray children = firstData.getJSONArray("children");
List<GalleryItem> items = new ArrayList();
for(int i = 0; i < children.length(); i++ ){
JSONObject jsonObject = children.getJSONObject(i);
JSONObject childrenObject = jsonObject.getJSONObject("data");
GalleryItem item = new GalleryItem();
item.setTitle(childrenObject.getString("title"));
item.setUrl(childrenObject.getString("url"));
item.setThumbnail(childrenObject.getString("thumbnail"));
//if(!childrenObject.getString("url").endsWith(".jpg")){
// continue;
// }else{
items.add(item);
// }
}
return items;
}
private class GalleryHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private ImageView mImageView;
private TextView mTextView;
private String mUrl;
public GalleryHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
mImageView = (ImageView) itemView.findViewById(R.id.country_photo);
mTextView = (TextView) itemView.findViewById(R.id.country_name);
}
public void bindImage(GalleryItem item ){
Picasso.with(MainActivity.this).load(item.getThumbnail()).tag(MainActivity.this).into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
Palette pallete = Palette.from(bitmap).generate();
int color = pallete.getMutedColor(MainActivity.this.getResources().getColor(android.R.color.black));
mTextView.setBackgroundColor(color);
mImageView.setImageBitmap(bitmap);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
}
public void bindUrl(String url){
mUrl = url;
}
#Override
public void onClick(View view) {
Intent i = new Intent(MainActivity.this, ItemActivity.class);
i.putExtra("url", mUrl);
Log.i(mUrl, mUrl);
startActivity(i);
}
}
private class GalleryAdapter extends RecyclerView.Adapter<GalleryHolder>{
private List<GalleryItem> mImages;
private Context mContext;
public GalleryAdapter(List<GalleryItem> images, Context context){
mContext = context;
mImages = images;
}
#Override
public GalleryHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
View view = inflater.inflate(R.layout.list_item, parent, false);
return new GalleryHolder(view);
}
#Override
public void onBindViewHolder(GalleryHolder holder, int position) {
holder.mTextView.setText(mImages.get(position).getTitle());
holder.mImageView.setImageBitmap(null);
holder.bindImage(mImages.get(position));
holder.bindUrl(mImages.get(position).getUrl());
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemCount() {
return mImages.size();
}
}
}
I just have one recyclerview that loads images and text from a REST json based api, the list has only a CardView and one TextView, the text loads fine but the image only show when i scroll the Card out of screen, that also ONLY happens to the first 2 positions of the list, heres a video to explain better:
I dont know how to embbed videos here
As you can see the first 2 images only loads when i scroll them out of the screen
Your problem is with Target (Picasso only keeps a weak reference to the Target object)
What you can do:
Make a strong reference to the Target object (keep it as a field of ViewHolder, for example):
private class GalleryHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private ImageView mImageView;
private TextView mTextView;
....
com.squareup.picasso.Target target = new com.squareup.picasso.Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
mTextView.setBackgroundColor(Color.RED);
mImageView.setImageBitmap(bitmap);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {}
};
....
public void bindImage(GalleryItem item ){
Picasso.with(MainActivity.this).load(item.getThumbnail()).tag(MainActivity.this).into(target);
}
}
avoid using Target and use .into(mImageView) instead
Also, check this post: https://stackoverflow.com/a/26918731/1658267 (here you can find explanation, why this is happening)