How can I make Floating Action Button rotate on every click - java

I want the fab to rotate each time i click on it. But after trying, i achieved the rotation effect. But the problem i'm having is that it only work once. i.e on app startup.
Please help, i'm a beginner in this.
Below is the complete code i used.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context=".MainActivity">
<com.google.android.material.bottomappbar.BottomAppBar
android:id="#+id/bottom_app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:gravity="bottom"
android:backgroundTint="#color/design_default_color_background"
app:fabCradleMargin="15dp"
app:menu="#menu/app_bar_layout"
app:fabCradleVerticalOffset="20dp"
app:fabCradleRoundedCornerRadius="40dp"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fab_generate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#1D6837"
android:src="#drawable/generate"
app:layout_anchor="#id/bottom_app_bar"
android:contentDescription="generate"
android:clickable="true"
app:fabCustomSize="80dp"
app:maxImageSize="45dp"
android:layout_marginBottom="20dp"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.OvershootInterpolator;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import static androidx.core.view.ViewCompat.animate;
public class MainActivity extends AppCompatActivity {
private FloatingActionButton generateFab;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
generateFab = findViewById(R.id.fab_generate);
generateFab.setOnClickListener ( new View.OnClickListener() {
#Override
public void onClick(View v) {
final OvershootInterpolator interpolator = new OvershootInterpolator();
animate(generateFab).
setInterpolator(interpolator).
setListener(null).
rotation(360f).
withLayer().
setDuration(300).
withStartAction(null).
start();
}
});
}
}
Basically, I added onClickListener to my floating action button inside the onCreate method

Try this:
animate(generateFab).
setInterpolator(interpolator).
setListener(null).
rotation(generateFab.getRotation() + 360f).
withLayer().
setDuration(300).
withStartAction(null).
start();
Notice the line rotation(generateFab.getRotation() + 360f).
You rotate the view 360 degrees on the first click so this changes the view elements rotation attribute to 360, and because its already 360 (after the first rotation) it wont rotate again. So instead you want to keep adding 360 degrees to the current views rotation and it will work.
Update:
As per comment by #AHoneyBustard you could instead of rotation(...) use:
rotationBy(360f)

Related

Android: Why does calling viewToFront() on a SeekBar not bring it to the top of the UI?

I am trying to make a hidden SeekBar (originally with visibility = "gone") visible and be displayed on top of a black background LinearLayout that covers the entire screen. However, when I run my code, I just see the fullscreen LinearLayout and I do not see a SeekBar that is on top of that LinearLayout:
Below is my code:
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000000"
android:orientation="vertical" >
</LinearLayout>
<SeekBar
android:id="#+id/seekbar"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="0dp"
android:padding="0dp"
android:max="100"
android:progressDrawable="#android:color/transparent"/>
</LinearLayout>
MainActivity.java:
package com.example.changingimageviewwidth;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.SeekBar;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Make the image preview box visible
SeekBar seekbar = findViewById(R.id.seekbar);
seekbar.setVisibility(View.VISIBLE);
seekbar.bringToFront();
// Place the image preview box at a specified location
seekbar.setX(150);
seekbar.setY(150);
seekbar.setVisibility(View.VISIBLE);
seekbar.bringToFront();
// Place the image preview box at a specified location
seekbar.setX(150);
seekbar.setY(150);
}
}
This doesn't answer your question but it may solve the problem. You can use a ConstraintLayout to position the SeekBar. It is a flat hierarchy so you can stack views on top of each other and then you can use visibility to hide/show it, instead of moving it into place it is always there.

Android Floating Action Button not being recognized

When I look at my code in the editor, nothing seems to be a problem. However, when I run the code on my phone and try to go from one activity to another which features a floating action button, the floating action button cannot find the view by Id despite the ID being exactly the same in both java and XML.
My Java:
package com.test.app.app2_test1;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class TermsOfUse extends AppCompatActivity {
FloatingActionButton mFloatingActionButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.terms_of_use);
mFloatingActionButton = (FloatingActionButton) mFloatingActionButton.findViewById(R.id.terms_back_fab);
mFloatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
}
}
My XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.test.app.app2_test1.TermsOfUse"
android:background="#color/backdrop">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="44dp"
android:orientation="vertical">
</ScrollView>
<View
android:layout_gravity="bottom"
android:layout_width="match_parent"
android:layout_height="44dp"
android:background="#color/colorPrimary"
android:elevation="4dp"/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/terms_back_fab"
android:layout_gravity="bottom"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_margin="16dp"
android:src="#drawable/ic_arrow_back"
app:pressedTranslationZ="12dp"/>
</android.support.design.widget.CoordinatorLayout>
The message that I get in my console is the following:
Attempt to invoke virtual method 'android.view.View android.support.design.widget.FloatingActionButton.findViewById(int)' on a null object reference
Any help would be appreciated.
You are treating a view as a child of its own!
Replace:
mFloatingActionButton = (FloatingActionButton) mFloatingActionButton.findViewById(R.id.terms_back_fab);
With:
mFloatingActionButton = (FloatingActionButton)findViewById(R.id.terms_back_fab);

Android - onTouchListener ClassCastException

I would like to use viewSwitcher to switch between two layouts. It works with a button, but I would like to switch with touching the screen. I've found an onTouchListener example and i tried to implemet some kind of similar, but I did not manage to.
In my main.xml i got one Linear Layout which contains a ViewSwitcher and two other LinearLayout. These are the layouts i want to switch.
here it is:
<ViewSwitcher
android:id="#+id/viewSwitcher"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inAnimation="#android:anim/slide_in_left"
android:outAnimation="#android:anim/slide_out_right" >
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/firstlayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/bg"
android:orientation="vertical" >
<ImageView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="#drawable/titlebar" />
<Button
android:id="#+id/somebut"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="30px"
android:background="#drawable/but" />
</LinearLayout>
<LinearLayout
android:id="#+id/secondlayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Second layout" >
</TextView>
</LinearLayout>
</ViewSwitcher>
and my code:
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.LinearLayout;
import android.widget.ViewSwitcher;
public class SwitcherActivity extends Activity {
private float downXValue;
private View firstView;
private View SecondView;
private ViewSwitcher vs;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
vs = (ViewSwitcher)findViewById(R.id.viewSwitcher);
firstView= findViewById(R.id.firstlayout);
secondView = findViewById(R.id.secondlayout);
LinearLayout first = (LinearLayout) findViewById(R.id.firstlayout);
first.setOnTouchListener((OnTouchListener) this);
}
public boolean onTouch(View arg0, MotionEvent arg1) {
switch (arg1.getAction()){
case MotionEvent.ACTION_DOWN:{
// store the X value when the user's finger was pressed down
downXValue = arg1.getX();
break;
}
case MotionEvent.ACTION_UP:{
// Get the X value when the user released his/her finger
float currentX = arg1.getX();
// going backwards: pushing stuff to the right
if (downXValue < currentX)
{
if (vs.getCurrentView() != myFirstView)vs.showPrevious();
}
// going forwards: pushing stuff to the left
if (downXValue > currentX)
{
if (vs.getCurrentView() != mySecondView)
vs.showNext();
}
break;
}
}
return true;
}
}
My problem is, that i got ClassCastException in the line which contains the following:
first.setOnTouchListener((OnTouchListener) this);
Your activity has to implement OnTouchListener so that "this" can be used as the listener. Right now it's trying to cast an Activity to an OnTouchListener which is what's throwing the ClassCastException.
You also need to override the OnTouchListener methods to customize the way the touches are handled.

How to focus to the top of newly generated text in textView?

I have a simple jokes application. When you press the button you get new joke. If the previous one was bigger than the screen you can scroll it down. If you go down to the bottom and you go to the next joke, you are transfered to the bottom of the newly generated joke, but i want it to go to the top, and automatically display the start of the joke. How can i do this ?
I assume it would be done via the java code.
Thank you for your time.
Use the scrollTo(int x, int y) method, i like to have ScrollView around my TextView but i think the same thing will work for a TextView only. hope you understand!
Rolf
Example
xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ScrollView
android:id="#+id/scroll"
android:layout_width="fill_parent"
android:layout_height="130dp" >
<TextView
android:id="#+id/text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="long\n\n\n\n\n\n\n\n long\n\n\n\n\n\n\n very text here!" />
</ScrollView>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="joke" />
</LinearLayout>
java:
package org.sample.example;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ScrollView;
import android.widget.TextView;
public class AutoscrollActivity extends Activity implements OnClickListener {
/** Called when the activity is first created. */
private Button new_joke;
private TextView joke;
private ScrollView scroll;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new_joke = (Button) this.findViewById(R.id.button);
new_joke.setOnClickListener(this);
joke = (TextView) this.findViewById(R.id.text);
scroll = (ScrollView) this.findViewById(R.id.scroll);
}
#Override
public void onClick(View v) {
joke.setText("Long\n\n\n\n\n\n\n\n joke \n\n\n\n\n\n\n\nlong joke joke");
scroll.scrollTo(0, 0);
}
}

Changing the position of the thumb of the SeekBar using a different Button

I'm trying to move the position of the seekbar using a button. Basically I have a seekbar from 0 to 100. and I have button presents set up at arbitrary values (40,50,60 etc). When I try to set the progress on the seekbar via button, I get a fault.. I've already initialized the seekBar in the onCreate() method.
SeekBar seekBar = (SeekBar) findViewById(R.id.seekBar1);
currentProgress = 40;
seekBar.setMax(100);
seekBar.setProgress(currentProgress);
button40.setOnClickListener(button40Listener);
But when use the below, it crashes.
private OnClickListener button40Listener = new OnClickListener() {
public void onClick(View v) {
currentProgress = 40;
seekBar.setProgress(currentProgress);
}
}
This seems straight-forward. Any ideas?
You shouldn't need to put up another Seekbar. The initial one should be fine. Without the exception message and stack trace I'm not sure what is causing the crash. However, I just coded an example and works as you would expect. Perhaps by looking at my example you can identify your issue.
SeekbarTest.java:
package com.example.seekbartest;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;
public class SeekbarTest extends Activity {
/** Called when the activity is first created. */
private SeekBar seekBar;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
seekBar = (SeekBar)findViewById(R.id.seekBar1);
Button fortyPctButton = (Button)findViewById(R.id.buttonFortyPct);
fortyPctButton.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
seekBar.setProgress(40);
}
});
Button sixtyPctButton = (Button)findViewById(R.id.buttonSixtyPct);
sixtyPctButton.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
seekBar.setProgress(60);
}
});
Button eightyPctButton = (Button)findViewById(R.id.buttonEightyPct);
eightyPctButton.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
seekBar.setProgress(80);
}
});
}
}
And here is the main.xml it is referencing for the layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent"
android:text="#string/hello"
android:id="#+id/textView1"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"/>
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/seekBar1"
android:layout_below="#+id/textView1"
android:layout_alignLeft="#+id/textView1"
android:layout_alignRight="#+id/textView1"/>
<Button
android:layout_width="wrap_content"
android:text="40%"
android:id="#+id/buttonFortyPct"
android:layout_height="wrap_content"
android:layout_below="#+id/seekBar1"
android:layout_alignLeft="#+id/seekBar1"/>
<Button
android:layout_width="wrap_content"
android:text="60%"
android:id="#+id/buttonSixtyPct"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/buttonFortyPct"
android:layout_alignTop="#+id/buttonFortyPct"
android:layout_alignBottom="#+id/buttonFortyPct"/>
<Button
android:layout_width="wrap_content"
android:text="80%"
android:id="#+id/buttonEightyPct"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/buttonSixtyPct"
android:layout_alignTop="#+id/buttonSixtyPct"
android:layout_alignBottom="#+id/buttonSixtyPct"/>
</RelativeLayout>
Just create a new android app and replace the generated code + layout with the example above. It should work for you.
Good luck,
Craig

Categories

Resources