I want to implement the Extended FAB button in the format mentioned on the material website (https://kstatic.googleusercontent.com/files/8f9b57829c943c97be7c4b2485cf678f041dfe7c7ef523cfb2e97f1aeee21431f83d98cc07befeeed904fabb258298e3a7ac95f9da5d3da7a4adcff658cea851)
https://material.io/components/buttons-floating-action-button#types-of-transitions
Kindly help on how to achieve the same.
You can use the Material motion and the Transition between Views.
For example define in your layout:
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="#+id/root"
..>
<com.google.android.material.card.MaterialCardView
android:id="#+id/end_card"
android:visibility="gone" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fab"
.. />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Then just define the MaterialContainerTransform:
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showEndView(fab);
}
});
with:
private void showEndView(View startView) {
// Construct a container transform transition between two views.
MaterialContainerTransform transition = new MaterialContainerTransform();
transition.setScrimColor(Color.TRANSPARENT);
transition.setInterpolator(new FastOutSlowInInterpolator());
//set the duration....
//Define the start and the end view
transition.setStartView(startView);
transition.setEndView(endCard);
transition.addTarget(startView);
// Trigger the container transform transition.
TransitionManager.beginDelayedTransition(root, transition);
if (startView != null) {
startView.setVisibility(View.INVISIBLE);
}
if (endCard != null) {
endCard.setVisibility(View.VISIBLE);
}
}
Note: it requires at least the version 1.3.0-alpha01.
Related
I am working on an app using geolocation and I want to set a layout VISIBLE when close to a point and GONE when too far from the point.
This is my xml :
<LinearLayout
android:visibility="gone"
android:id="#+id/slidePane"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
Then I use the ID in the activity as usual :
declare it in the class attribute :
private LinearLayout slidepane;
set it in the onCreate() method :
slidepane = (LinearLayout) findViewById(R.id.slidePane);
And then I try to update it in onLocationChanged() method as follows :
if (InterestPoint.CalculationByDistance(location, new LatLng(47.247801, -1.551883)) < 0.03) {
Toast.makeText(MainActivity.mContext, "InterestPoint close", Toast.LENGTH_SHORT).show();
slidepane.setVisibility(View.VISIBLE);
} else {
slidepane.setVisibility(View.GONE);
}
So the condition is correct since the Toast appears but the layout does not become visible, why?
Thank you.
EDIT : I am using https://github.com/umano/AndroidSlidingUpPanel and try to set the visibility of the second child (the sliding panel). I didn't see anything in the documentation about visibility. I can still access the children of the LinearLayout but not the container itself (and especialy the visibility).
Replace this:
slidepane.setVisibility(View.VISIBLE);
with this:
runOnUiThread(new Runnable() {
#Override
public void run() {
slidepane.setVisibility(View.VISIBLE);
}
});
Make sure you set the visibility of view at the time of initialization.
#Override
protected void onCreate(Bundle savedInstanceState) {
........
slidepane = (LinearLayout) findViewById(R.id.slidePane);
slidepane.setVisibility(View.GONE);
.......
//onLocationChanged() add ->
if (InterestPoint.CalculationByDistance(location, new LatLng(47.247801, -1.551883)) < 0.03) {
Toast.makeText(MainActivity.mContext, "InterestPoint close", Toast.LENGTH_SHORT).show();
slidepane.setVisibility(View.VISIBLE);
} else {
slidepane.setVisibility(View.GONE);
}
I am using the floating action button (fab) component from com.android.support:design:23.1.0 Library to generate my app's fabs.
But the first time I load a new activity with fab.hide() and try to make the icon visible through fab.show() after a button was clicked, there is no animation for the fab. This happens only the first time after loading a new activity. When I try that multiple times to hide and show the button, it is animated properly.
What is the issue here? It would be a charm to get it animated also right after an activity is loaded.
Java in activity:
fabSend = (FloatingActionButton) findViewById(R.id.fabSend);
fabSend.hide();
CompoundButton.OnCheckedChangeListener changeChecker = new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked){
// FAB on
fabSend.show();
} else {
// FAB off
fabSend.hide();
}
}
};
Layout.xml
<android.support.design.widget.FloatingActionButton
android:id="#+id/fabSend"
app:borderWidth="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_alignParentBottom="true"
android:layout_marginRight="#dimen/fab_margin"
android:layout_marginBottom="54dp"
android:src="#drawable/ic_check_white_24dp" />
I've had the same problem. In my fab xml I had visibility="gone", than I tried to show fab from the code by fab.show() - and animation was not working the first time. I've changed xml to visibility="invisible" and problem was solved.
Solved this one finally. I designed a new class to handle the reveal animation with a delay. Grab it here, initialize it and you're good to go. I found a pretty similar animation to the standard fab.show() at 50ms delay on it.
public static void showFabWithAnimation(final FloatingActionButton fab, final int delay) {
fab.setVisibility(View.INVISIBLE);
fab.setScaleX(0.0F);
fab.setScaleY(0.0F);
fab.setAlpha(0.0F);
fab.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
fab.getViewTreeObserver().removeOnPreDrawListener(this);
fab.postDelayed(new Runnable() {
#Override
public void run() {
fab.show();
}
}, delay);
return true;
}
});
}
The best way to achieve that is by simply setting your Fab's scaleX and scaleY to zero in XML. It is the easiest method and it also leaves your application code clean.
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleX="0"
android:scaleY="0"
android:visibility="invisible"/>
According to docs:
android.support.design.widget.FloatingActionButton
public void show()
Shows the button. This method will animate the button show if the
view has already been laid out.
So, to make it animate the first time you can write you own animation to animate it when it's not currently laid out
/**
* Unlike {#link FloatingActionButton#show()} animates button even it not currently
* laid out
* #param fab fab to show
*/
#SuppressLint("NewApi")
public static void show(FloatingActionButton fab) {
if (ViewCompat.isLaidOut(fab) ||
Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
fab.show();
} else {
fab.animate().cancel();//cancel all animations
fab.setScaleX(0f);
fab.setScaleY(0f);
fab.setAlpha(0f);
fab.setVisibility(View.VISIBLE);
//values from support lib source code
fab.animate().setDuration(200).scaleX(1).scaleY(1).alpha(1)
.setInterpolator(new LinearOutSlowInInterpolator());
}
}
I am working on Android L trying to implement a drawer menu that overlaps the action bar. I have done it the normal way where it appears under the action bar, as described here: http://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer/.
It was done in the google IO 2014 app and I would like to replicate it. I have been looking through the code (https://github.com/google/iosched) but I can't figure out how they done it.
Here is an image:
Does anyone have any idea how they done it?
To obtain this you have to use the new Toolbar.
You can use a layout like this:
<Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
android:theme="#style/ActionBarThemeOverlay"
android:id="#+id/toolbar_actionbar"
android:layout_width="match_parent"
android:layout_height="?android:actionBarSize" />
Then in your activity you can do:
Toolbar mActionBarToolbar = (Toolbar) mActivity.findViewById(R.id.toolbar_actionbar);
if (mActionBarToolbar != null) {
mActivity.setActionBar(mActionBarToolbar);
}
Finally you have to setup the toolbar to work with the navigation drawer:
if (mActionBarToolbar != null) {
mActionBarToolbar.setNavigationIcon(R.drawable.ic_navigation_drawer);
mActionBarToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mDrawerLayout.isDrawerOpen(Gravity.START)) {
mDrawerLayout.closeDrawer(Gravity.START);
} else {
mDrawerLayout.openDrawer(Gravity.START);
}
}
});
}
Pay attention because currently the new Toolbar class is only API-21.
I am having following layout
<merge>
<LinearLayout
android:id="#+id/ll_main"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
/>
<LinearLayout
android:id="#+id/ll_sub"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
/>
</merge>
What I want to do is to show/hide the ll_sub layout on runtime through setVisibility() but it is not working.
When I am setting android:visibility="gone" (also I had checked with invisible) from the xml of ll_sub then it is not displayed on the screen and this time when I use setVisibility() to show this layout on runtime, it is displayed but when I try to hide this layout once it is displayed then it is not hiding.
EDIT
I am trying to show/hide this linear layout on click of a button.
LinearLayout ll;
Button minimize;
int visibility=0;
#Override
public void onCreate(Bundle savedInstanceState)
{
ll=(LinearLayout)findViewById(R.id.ll_sub);
minimize=(Button)findViewById(R.id.minimize);
minimize.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
if(visibility==0)
{
visibility=2;
}
else
{
visibility=0;
}
ll.setVisibility(visibility);
}
});
}
It looks like you're setting the wrong constants for changing view visibility.
GONE == 8
INVISIBLE == 4
VISIBLE == 0
However, you should never rely on the actual values that Android happened to designate to represent their constants. Instead use the the values defined in the View class: View.VISIBLE, View.INVISIBLE, and View.GONE.
// snip...
if(visibility == View.VISIBLE)
{
visibility = View.GONE;
}
else
{
visibility = View.VISIBLE;
}
ll.setVisibility(visibility);
And don't forget to call invalidate() on the view :)
You should use the Constants provided by View
View.INVISBLE, View.VISIBLE, View.GONE
and also invalidate your View
Can anyone tell me what's wrong with this implementation? All I want to do here is have two overlapping views that swap places when you tap the screen. Unless I'm just using it wrong, View.bringToFront() does nothing?
Below is all the code in my app. Note that I added padding to the 'backView' just to make sure the two were actually overlapping. Indeed I could see both on the screen. While tapping the top view does indeed trigger the onClick method, nothing visibly changes in response to the calls to bringToFront.
public class MainActivity extends Activity implements OnClickListener {
private ImageView frontView;
private ImageView backView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
frontView = (ImageView) findViewById(com.example.R.id.FrontView);
backView = (ImageView) findViewById(com.example.R.id.BackView);
frontView.setOnClickListener(this);
backView.setOnClickListener(this);
backView.setPadding(10,0,0,0);
}
private boolean flag;
public void onClick(View v) {
if (!flag) {
backView.bringToFront();
}
else {
frontView.bringToFront();
}
flag = !flag;
}
}
and the corresponding 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"
>
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/FrontView"
android:src="#drawable/front"
/>
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/BackView"
android:src="#drawable/back"
/>
</RelativeLayout>
Maybe it's the layout I'm using? I'm not sure... I've tried FrameLayout and LinearLayout as well.
I would try swapping content views instead of ImageViews.
Put each imageView in a different layout and then it is easy:
public void onClick(View v) {
if (!flag) {
setContentView(R.layout.main_front);
frontView = (ImageView) findViewById(com.example.R.id.FrontView);
frontView.setOnClickListener(this);
}
else {
setContentView(R.layout.main_back);
backView = (ImageView) findViewById(com.example.R.id.BackView);
backView.setOnClickListener(this);
}
flag = !flag;
}
There are a couple of Components that you can use that do this for you.
ViewAnimator, ViewFlipper and ViewSwitcher. You can set the animations you require etc and they hand the rest.
here's one example.
http://www.androidpeople.com/android-viewflipper-example/
Given your example, do you have to call invalidate() on the parent after you've called bringToFront() ?