onBindViewHolder increase position onClickListener - java

I have an activity with two buttons Next and Previous and a textview, I would like to update the textview content each time I click Next or Back
For example, If I click Next the textview should show me content from the next position or vice versa.
I think that I should be using a loop but it gives me an error when I try to do that and when I add 1 to the position (i+1) it works but it only gives me the second position, I want to get all the positions not only the second one. I don't really know if my question is clear, Hope it is :)
onBindViewHolder
#Override
public void onBindViewHolder(#NonNull final MyViewHolder myViewHolder, #SuppressLint("RecyclerView") final int i) {
myViewHolder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String nextContent = listItems.get(i).getContent();
String previousContent = listItems.get(i).getContent();
Intent intent = new Intent(v.getContext(), Main2Activity.class);
intent.putExtra("next", nextContent);
intent.putExtra("prev", previousContent);
v.getContext().startActivity(intent);
}
});
}
Main2Activity
btnNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
itemTextView.setText(nextContent);
}
});
btnPrev.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
itemTextView.setText(prevContent);
}
});

It's bad practice to set click listeners in the onBindViewHolder method.
Why? Because onBindViewHolder is called each time the views are recycled for the new content to be displayed on the screen. Say you have a list of 1000 elements with 10 of them visible on the screen.
You scroll it to the end => Then onBindViewHolder would be called 990 times => 990 click listeners set.
You also want to dodge costly operations in onBindViewHolder() because your scrolling would be potentially slowed down.
More tips here:
Recyclerview(Getting item on Recyclerview)

A loop isn't the answer here, a loop is for automating something. This is an event (the user interacted) so it's not suitable.
The algorithm you probably want is basically the following:
User clicked an item
Find out the item index
Increment the index
Find the item with that index (by asking the list)
If it exists, do something with it
However, the issue in the code you posted is that your 'nextContent' is always the current item. So you need the following change (but be careful about bounds):
String nextContent = listItems.get(i+1).getContent();
String previousContent = listItems.get(i-1).getContent();
You current code isn't using a loop, so the onBind method should be called once for each value of i so it should not always be the second item
After your comments it appears you have buttons unrelated to the list, so now what you need to do is make it so every time you click an item in the RV or a Next/Prev, you store the correct index (as you have no access to i)
In the activity:
private int currentTextItem = 0;
public void setCurrentTextItem(int i) {
currentTextItem = i;
//the dots here will be how you get the text from the item
// probably recyclerView.findViewHolderForAdapterPosition(pos)
myTextView.setText( ... );
}
In your view holder code:
myViewHolder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//(You should have some kind of call back from viewholder to activity)
activity.setCurrentTextItem(i);
}
});
Then your next/prev:
btnNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setCurrentTextItem(currentTextItem + 1);
}
});
btnPrev.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setCurrentTextItem(currentTextItem - 1);
}
});

Related

How to Visible/Invisible using OnClickListener?

I am working on FAQ page I don't want to use Expandable list view and stuff.
So I set 2 TextViews(1 for Question and 1 for Answer) and made one clickable.
The above image shows when the first textview mfaq is clicked it sets second one mAns to visible.
The below code works well to Set the mAns textview visible:
public class faq extends AppCompatActivity {
TextView mfaq,mAns;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_faq);
mfaq=findViewById(R.id.faq);
mAns=findViewById(R.id.ans);
mfaq.setOnClickListener(new View.OnClickListener() {
int counter=0; //setting counter to count onclick
#Override
public void onClick(View view) {
++counter; //incrementing counter first click
if(counter==1){
mAns.setVisibility(View.VISIBLE);
}
//this sets mAns visible , but when i click on it again i want it to hide the text view
counter=0; //resetting the counter
}
});
}
}
So I want to set the visibilty to gone when the textview is clicked again(Should function like Click-visible,ClickAgain-Invisible,Repeat).
Note-I am a beginner please try to explain me what the code is doing so I learn more :)
Thanks.
If I understand well you wanna hide/show your textview each time you click on the other text?
mfaq.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mAns.getVisibility() == View.VISIBLE){
mAns.setVisibility(View.GONE);
}
else
mAns.setVisibility(View.VISIBLE);
}
});

Call void method from another method in the same class

At first my main problem was at how to call a method from the same class, even tough I think I found a way to do this, it's not working as I expected, and I would like to know what would be the best approach to my case.
This is the code I'm working on:
public class EscolhaAtendimento extends AppCompatActivity {
private ViewPager mSlideViewPager;
private LinearLayout mDotLayout;
String TAG = "TasksSample";
private TextView[] mDots;
private SliderAdapter sliderAdapter;
Dialog myDialog;
#Override
public void onCreate (Bundle SavedInstanceState){
super.onCreate(SavedInstanceState);
setContentView(R.layout.escolha_atendimento);
mSlideViewPager = findViewById(R.id.slideViewPager);
mDotLayout = findViewById(R.id.dotsLayout);
sliderAdapter = new SliderAdapter(this);
mSlideViewPager.setAdapter(sliderAdapter);
addDotsIndicator(0);
mSlideViewPager.addOnPageChangeListener(viewListener);
myDialog = new Dialog(this);
}
public void addDotsIndicator(int position){
mDots = new TextView[8];
mDotLayout.removeAllViews();
for (int i= 0; i < mDots.length; i++){
mDots[i] = new TextView(this);
mDots[i].setText(Html.fromHtml("•"));
mDots[i].setTextSize(35);
mDots[i].setTextColor(getResources().getColor(R.color.colorTransparentWhite));
mDotLayout.addView(mDots[i]);
}
if (mDots.length > 0){
mDots[position].setTextColor(getResources().getColor(R.color.colorWhite));
}
}
ViewPager.OnPageChangeListener viewListener = new ViewPager.OnPageChangeListener(){
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected (int i) {
switch (i) {
case 0: {
myDialog.show();
}
addDotsIndicator(i);
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
};
public void ShowPopup(View v) {
TextView txtclose;
//Button btnFollow;
myDialog.setContentView(R.layout.pop_upfinal);
txtclose = myDialog.findViewById(R.id.txtclose);
txtclose.setText("X");
//btnFollow = (Button) myDialog.findViewById(R.id.btnfollow);
txtclose.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
myDialog.dismiss();
}
});
myDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
myDialog.show();
}
}
This class is an activity that on user swipe, the text and image from the buttons will change, even though their IDs will stay the same. (That's controlled by another class, it's working well).
Now, I wanted the image button on the activity do something different depending on which page is selected, and that's why there is a initial switch on the onPageSelected method, inside the Page change listener. The image button in the layout has the android:onClick="ShowPopup" tag, and I guess that also complicates things for me, if I wanted it to do something different in that same activity? Also, calling it that way on the switch, every time I change pages, and go back to the first one the popup window will open, since my call is explicit there. (As I said, even tough I found a way to somehow call my method, or at least it's result, it's not working as I expected).
Edit
I tried then changing it like this, so that the button wouldn't rely on the android:onClick="ShowPopup" Tag, and also wouldn't need to call a void method directly on the switch:
Added
public ImageButton popupchoice;
And also this to onCreate method:
popupchoice = this.findViewById(R.id.imgslide1);
Inside the switch I called it like this to get the button ID:
popupchoice.setOnClickListener(image1);
And set the View.OnClickListener like this:
View.OnClickListener image1 = new View.OnClickListener() {
public void onClick(View v) {
TextView txtclose;
//Button btnFollow;
myDialog.setContentView(R.layout.pop_upfinal);
txtclose = myDialog.findViewById(R.id.txtclose);
txtclose.setText("X");
//btnFollow = (Button) myDialog.findViewById(R.id.btnfollow);
txtclose.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
myDialog.dismiss();
}
});
myDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
myDialog.show();
}
};
But that returns me:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setOnClickListener(android.view.View$OnClickListener)' on a null object reference at .EscolhaAtendimento$1.onPageSelected(EscolhaAtendimento.java:81) Line 81 is the one inside the switch with the popupchoice.setOnClickListener(image1).
This error happens on page change, when coming back to the first Page, and also the button click won't work anymore.
I think you can use
EscolhaAtendimento.this.ShowPopup from inside your switch.

When last string removed it causes app to crash

Ok.. Here is my problem.
I have an arraylist of stings with 10 items in it.
Then I randomize the list and display a random string in a textview.
With the last string removed the app crashes. Any tip to fix that?
Here is the code:
Collections.shuffle(learnlist);
showlearntv.setText(learnlist.get(0));
nextlearn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showlearntv.setText(learnlist.get(1));
learnlist.remove(0);
You are attempting to call get(1) on a list that may contain less than two elements.
You should add some safety checks. E.g.:
nextlearn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!learnlist.isEmpty()) {
learnlist.remove(0);
}
if (!learnlist.isEmpty()) {
showlearntv.setText(learnlist.get(0));
}
}
On the click handler, remove the item first,
learnlist.remove(0)
Then if the list has any items,
showlearntv.setText(learnlist.get(0));
Else do something else.

Get text of dynamic generated TextView when clicking on it

I'm running through a for-loop and am generating TextViews that should be clickable because I want to start then an intent and pass the url as parameter as well as the source.
So, I've tried this
articleURL[i].setPaintFlags(articleURL[i].getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
articleURL[i].setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//System.out.println(articleURL[v.getId()].getText().toString());
System.out.println(v.getId());
}
});
The problem i encounter is that the v.getId() is always 0. And when i use the commented code
System.out.println(articleURL[v.getId()].getText().toString());
I get an exception that says
java.lang.ArrayIndexOutOfBoundsException: length=10; index=-1
I just need the content of the TextView i clicked on. How exactly do i get it? articleURL[i] doesn't work because he doesn't know i then. How can v.getId() always be -1? No matter which one I click?
This here is the complete for-loop
TextView articleURL = new TextView[hashMapSize];
for (int i = 0; i < hashMapSize; i++) {
articleURL[i] = new TextView(getActivity());
articleURL[i].setPaintFlags(articleURL[i].getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
articleURL[i].setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println(articleURL[v.getId()].getText().toString());
//System.out.println(v.getId());
}
});
}
You actually get the View in the parameter. Just cast it to TextView and call getText()
public void onClick(View v) {
Log.d("text",((TextView) v).getText().toString());
}
Also don't use System.out.println. This is Android, not desktop Java, and coding android is a huge difference to normal Java. You should get a book on Android and read it, otherwise your apps will start crashing pretty soon and you won't have any chance to fix them.
You may try the following:
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println(((TextView)v).getText());
}
};
// ... some loop
articleURL[i].setOnClickListener(listener);
If you also want to get index of item, try this:
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println(v.getTag());
}
};
// ... some loop
articleURL[i].setTag(i);
articleURL[i].setOnClickListener(listener);
Try this..
use this as globel
TextView articleURL[];
and then initial the articleURL like below
articleURL = new TextView[hashMapSize];
and then if your extends fragement means use below
articleURL[i] = new TextView(getActivity());
extends activity means
articleURL[i] = new TextView(this);
and
System.out.println(((TextView)v).getText().toString());

Android Notification Area Customization

I don't know whether this question get minus points, but I searched every where and my last resort is stackoverflow.
I need to add five buttons to notification area in horizontally. And each button I need to add even listener. I know it is possible to do with RemoteViews. But I never seen anyone adding event listener to each element.
These are the references if anyone need to refer.
Notifications Documentation
How to create a custom notification on android
SlidingDrawer API
You can add 5 anonymous listeners, or a single named listener.
Anonymous:
Button b1 = new Button(...);
b1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// first listener's code goes here
}
});
Button b2 = new Button(...);
b2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// second listener's code goes here
}
});
...
named is much the same, but contains a switch statement to differentiate what happens:
View.OnClickListener myListener = new View.OnClickListener() {
public void onClick(View v) {
String buttonTitle = ((Button)v).getText();
if ("title1".equals(buttonTitle)) {
// do things for the first button's click
} else if ("title2".equals(buttonTitle)) {
// do things for the second button's click
}
...
}
});
...

Categories

Resources