I'm having a problem when setting the visibility of two image buttons one on top of the other. The idea is to implement a play/pause control. The problem is that the only part where setting the visibility actually works is in the click listeners of the buttons. If I try to change it somewhere else nothing happens. Any idea why is this happening?
playBtn.setOnClickListener(new OnClickListener() {//PLAY BUTTON LISTENER
public void onClick(View v) {
playBtn.setVisibility(ImageButton.GONE);
pauseBtn.setVisibility(ImageButton.VISIBLE);
mp.start();
}});
pauseBtn.setOnClickListener(new OnClickListener() {//PAUSE BUTTON LISTENER
public void onClick(View v) {
pauseBtn.setVisibility(ImageButton.GONE);
playBtn.setVisibility(ImageButton.VISIBLE);
mp.pause();
}});
final class SeekBarTask extends TimerTask {
public SeekBarTask(int duration) {
}
#Override
public void run() {
if(seekBar.getProgress() >= mp.getDuration()) {//IF SONG HAS FINISHED...
pauseBtn.setVisibility(ImageButton.GONE);//THESE ONES
playBtn.setVisibility(ImageButton.VISIBLE);//DOESN'T WORK
mp.stop();
}
else {
seekBar.incrementProgressBy(100);
}
}
}
I would recommend just changing the icon of one ImageButton.
I would think only one of two things could be happening. Either this code never gets hit, or the variables are not referring to the same object instances you're expecting them to. Have you put a breakpoint inside that condition? I would check that a break point even gets hit in there, and then check that the variables are pointing at the correct button instances.
Without seeing the rest of the code I have to ask...why are you checking on a progress bar for a "finished playing" condition versus using the media players on completion callback?
I'm doing something very similar, and I use the MediaPlayer's OnCompletionListener to flip the visibility of my buttons.
I don't remember the details of Android GUI manipulation but could it have to do that you're doing it from another thread and you're not supposed to?
i noticed that setting an ImageButton to View.INVISIBLE is not working when you have set an Animation to it. you have to remove the Animation then make it Invisible. bad pitfall i think...
Related
I have a Recyclerview where there is a button onclicklistener in the viewholder constructor:
public ViewHolder(View itemView)
{
super(itemView);
...
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
...
}
}
}
Each item also has a countdown, every second the countdown is decremented and a progressbar of the item is updated to display the time left.
The timer is done with a runnable:
countdownHandler.postDelayed(countdownRunnable, 1000);
which then iterates through all the items, decrements the countdown and notifies the adapter:
countdownRunnable = new Runnable()
{
#Override
public void run()
{
Iterator<Item> iterator = countdownTasks.iterator();
while (iterator.hasNext())
{
item.decrementCountdown();
adapter.notifyItemChanged(items.indexOf(item));
}
if (countdownTasks.size() > 0)
countdownHandler.postDelayed(countdownRunnable, 1000);
}
}
Here is my problem, it also occurs if there is only one item in the list.
I press the button and is in the pressed state, but when the countdown update triggers, the button is no longer pressed. Releasing the button doesn't activate the button as it should. If I remove the countdown, it works properly.
I don't change the button in onBindViewHolder and I am not scrolling since there is only one item. Is this expected bahavior, that all button presses get canceled as soon as notifyItemChanged is called or am I doing something wrong? Does this even work with the onClickListener or do I need an onTouchListener and save the touchdown state in the item and reset it every update?
Thank you!
Edit:
I found out, that if I set
recyclerView.setItemAnimator(null);
it works without problems. Does anyone know why that is the case and how I can still get animation without the hassle of remembering all the states?
When you call adapter.notifyItemChanged(items.indexOf(item)); it rebind view for that position, which is fresh view stored in ViewHolder & don't have a pressed state & that's why it loses button state.
You can do it by using OnTouchListener and storing states as you mentioned in question.
I am writing as anshwer since i don't have reputation for comment.
I'm trying to do something like this:
When I go to this activity I have what is in black and some objects like EditText boxes.
Once I press the button I want those EditBoxes an other stuff that is up there to stay visible but unable to be edited (that's easy to do from code overriding onClick).
But at the same time I also want to load some layout down inside the same activity (from an xml) and change the button function to act over the objects of the new layout.
Could anyone give me an idea on how to do this two things staying in the same activity?
Update:
public void createButton(){
create_button.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
editText1.setEnabled(false);
editText2.setEnabled(false);
hidden_layout.setVisibility(View.VISIBLE);
create_button.setText("New text");
}
});
}
On the first click I want the button to do that. But once it's pressed I want it to do another thing. How could I do that?
(that's easy to do from code overriding onClick).
Actually I would recommend enable or disable which is easier to trace by using
view.setEnabled(bool);
as for the other question I'd recommend adding the layout from the start with setting visibility to GONE and when needed set the visibility to VISIBLE
view.setVisibility(View.VISIBLE);
view.setVisibility(View.GONE);
Ok, I've realized it was a dumb question, just add a flag an edit it:
public void createButton(){
create_button.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!button_pressed) {
editText1.setEnabled(false);
edittext2.setEnabled(false);
hidden_layout.setVisibility(View.VISIBLE);
create_button.setText("New text");
button_pressed=true;
}
else{
create_button.setText("Second click");
create_button.setEnabled(false);
}
}
});
}
}
I have a button that is set to VISIBLE under certain circumstances, then once its clicked its suppose to make the button INVISIBLE again but for some reason its not working. Here is my code,
if(variable == 2){
testButton.setVisibility(View.VISIBLE);
testButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
testButton.setVisibility(View.INVISIBLE);
test2Button.setVisibility(View.VISIBLE);
}
});
}
Have you tried displaying a toast when the button is clicked, just to see if that block of code is even executing? I don't see it, but I'm assuming you've actually declared a View associated with that button via 'findViewById'
EDIT:1
Do this
public void onClick(View view) {
view.setVisibility(View.INVISIBLE);
findViewById(R.id.<your test2Buttons ID>).setVisibility(View.VISIBLE);
}
Note: If you do View.GONE it will leave all area acquired by it and the other control will capture this area
where is with View.INVISIBLE it will maintain its acquired area
I have a layout which contains lots of images. What I have to do is when an image is clicked, I have to show its details. But I don't want to have onClickListeners for all the images. How can I achieve this?
You don't have to have different handlers for all the images. Instead use one handler for all the images. This would make your code cleaner, manageable and solve your problem too.
public void onCreate(Bundle bundle) {
//...
OnClickListener mHandler = new OnClickListener() {
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.img1:
//..
break;
case R.id.img2:
//....
break;
}
}
};
ImageButton btn1 = (ImageButton)findViewById(R.id.img1);
ImageButton btn2 = (ImageButton)findViewById(R.id.img2);
//...
btn1.SetOnClickListener(mHandler);
btn2.SetOnClickListener(mHandler);
//...
}
One Listener to rule them all.
Implement onClick() on an object, register it as listener
In onClick(), examine the View object passed as parameter to determine which of the images was clicked. You can do anything from getId() to casting it to (ImageView) and getting the actual image out.
Once you know which image was clicked, do what you will with it.
If you're looking to implement custom behavior for an ImageView (or whatever), and then have multiple instances of that type of view, you should subclass the ImageView and put your listener in there. Then you've got an encapsulated View that implements the custom behavior you want, and if you decide later that you want more or less or them, or to put them in another place, it's easy to move the View and its behavior without ripping apart your Activity.
Hi i have two textViews that i initially set its visibility to gone then animate in and become visible. now i want to make the invisible again but for some reason they're still showing on screen does anyone no why?
in my onCreate() i make the view gone
register = (TextView)findViewById(R.id.register);
register.setVisibility(View.GONE);
forgotpassword = (TextView)findViewById(R.id.forgotpw);
forgotpassword.setVisibility(View.GONE);
then later on i make it visible
public void run()
{
animations();
loginForm.setVisibility(View.VISIBLE);
register.setVisibility(View.VISIBLE);
forgotpassword.setVisibility(View.VISIBLE);
}
and then when a user presses a button i want the text views to become invisible so that they retain their layout but they stay visible on screen
signInBtn = (Button) findViewById(R.id.signin);
signInBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
signInProcess();
}
});
public void signInProcess() {
register.setVisibility(View.INVISIBLE);
forgotpassword.setVisibility(View.INVISIBLE);
setuploader.setVisibility(View.VISIBLE);
}
In Android when you animate something, It's just drawn somewhere else. The actual element is not moved. So when you animate signInBtn it's drawn somewhere else, but the actual button is not moved from the original position. So when you click the button the click handler is not called.
To avoid this set fillAfter = True in your animation so the button will actually get moved at the end of your animation.
Also, after animating a view in Android make sure you call View.clearAnimation() before trying to change its visibility.