SlidingPanelLayout not work well from right to left in android - android

I am creating SlidingPanelLayout from right to left for the filter purpose.The panel work fine it come out from right side and does animation but when Animation is stop it directly go to left side full but I want the ratio is 70% means right side panel came out 70% of the total screen and when click again it goes to hind and full Activity is display.
When first time Animation is stop the side panel goes to left side in the screenshot .But I want it right side.
ScreenShot :
but i want to display it write side and when click again it will go right side and hide again.
activity_inventory.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#e6e6e6"
android:id="#+id/mainLayout"
tools:context="com.example.softeng.jogi.InventoryActivity">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/backLayout"
tools:ignore="NotSibling">
</RelativeLayout>
<include
layout="#layout/filter"/>
<com.rey.material.widget.FloatingActionButton
android:id="#+id/button_bt_float_wave_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
style="#style/LightFABWaveColor"
android:layout_margin="8dp"/>
</RelativeLayout>
filter.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/filter_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0072BA"
android:visibility="invisible">
</RelativeLayout>
</RelativeLayout>
filterAnimation.java
public class FilterAnimation implements Animation.AnimationListener
{
Context context;
RelativeLayout filterLayout, otherLayout;
private Animation filterSlideIn, filterSlideOut, otherSlideIn, otherSlideOut;
private static int otherLayoutWidth, otherLayoutHeight;
private boolean isOtherSlideOut = false;
private int deviceWidth;
private int margin;
public FilterAnimation(Context context)
{
this.context = context;
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
deviceWidth = displayMetrics.widthPixels; // as my animation is x-axis related so i gets the device width and will use that width,so that this sliding menu will work fine in all screen resolutions
}
public void initializeFilterAnimations(RelativeLayout filterLayout)
{
this.filterLayout = filterLayout;
filterSlideIn = AnimationUtils.loadAnimation(context, R.anim.filter_slide_in);
filterSlideOut = AnimationUtils.loadAnimation(context, R.anim.filter_slide_out);
}
public void initializeOtherAnimations(RelativeLayout otherLayout)
{
this.otherLayout = otherLayout;
otherLayoutWidth = otherLayout.getWidth();
otherLayoutHeight = otherLayout.getHeight();
otherSlideIn = AnimationUtils.loadAnimation(context, R.anim.other_slide_in);
otherSlideIn.setAnimationListener(this);
otherSlideOut = AnimationUtils.loadAnimation(context, R.anim.other_slide_out);
otherSlideOut.setAnimationListener(this);
}
public void toggleSliding()
{
if(isOtherSlideOut) //check if findLayout is already slided out so get so animate it back to initial position
{
filterLayout.startAnimation(filterSlideOut);
filterLayout.setVisibility(View.INVISIBLE);
otherLayout.startAnimation(otherSlideIn);
}
else //slide findLayout Out and filterLayout In
{
otherLayout.startAnimation(otherSlideOut);
filterLayout.setVisibility(View.VISIBLE);
filterLayout.startAnimation(filterSlideIn);
}
}
#Override
public void onAnimationEnd(Animation animation)
{
if(isOtherSlideOut) //Now here we will actually move our view to the new position,because animations just move the pixels not the view
{
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(otherLayoutWidth, otherLayoutHeight);
otherLayout.setLayoutParams(params);
isOtherSlideOut = false;
}
else
{
margin = (deviceWidth * 70) / 100; //here im coverting device percentage width into pixels, in my other_slide_in.xml or other_slide_out.xml you can see that i have set the android:toXDelta="80%",so it means the layout will move to 80% of the device screen,to work across all screens i have converted percentage width into pixels and then used it
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(otherLayoutWidth, otherLayoutHeight);
params.leftMargin = margin;
params.rightMargin = -margin; //same margin from right side (negavite) so that our layout won't get shrink
otherLayout.setLayoutParams(params);
isOtherSlideOut = true;
dimOtherLayout();
}
}
#Override
public void onAnimationRepeat(Animation animation)
{
}
#Override
public void onAnimationStart(Animation animation)
{
}
private void dimOtherLayout()
{
AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.5f);
alphaAnimation.setFillAfter(true);
otherLayout.startAnimation(alphaAnimation);
}
}
InventoryActivity.java
public class InventoryActivity extends AppCompatActivity implements View.OnClickListener {
RelativeLayout filterLayout, findLayout;
FilterAnimation filterAnimation;
FloatingActionButton bffilter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_inventory);
assert getSupportActionBar() != null;
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
filterLayout = (RelativeLayout)findViewById(R.id.filter_layout);
findLayout = (RelativeLayout)findViewById(R.id.backLayout);
bffilter = (FloatingActionButton)findViewById(R.id.button_bt_float_wave_color);
bffilter.setOnClickListener(this);
filterAnimation = new FilterAnimation(this);
initializeAnimations();
}
private void initializeAnimations(){
final ViewTreeObserver filterObserver = filterLayout.getViewTreeObserver();
filterObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onGlobalLayout() {
filterLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
int deviceWidth = displayMetrics.widthPixels;
int filterLayoutWidth = (deviceWidth * 70) / 100;
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(filterLayoutWidth, RelativeLayout.LayoutParams.MATCH_PARENT);
filterLayout.setLayoutParams(params);
filterAnimation.initializeFilterAnimations(filterLayout);
}
});
final ViewTreeObserver findObserver = findLayout.getViewTreeObserver();
findObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onGlobalLayout() {
findLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
filterAnimation.initializeOtherAnimations(findLayout);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_inventory, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == android.R.id.home) {
this.finish();
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onClick(View v) {
int id = v.getId();
switch (id){
case R.id.button_bt_float_wave_color:
filterAnimation.toggleSliding();
break;
}
}
}
filter_slide_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/decelerate_interpolator">
<translate
android:fromXDelta="130%"
android:toXDelta="30%"
android:duration="1000" />
</set>
filter_slide_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/decelerate_interpolator">
<translate
android:fromXDelta="30%"
android:toXDelta="130%"
android:duration="1000"/>
</set>
other_slide_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/decelerate_interpolator">
<translate
android:fromXDelta="-70%"
android:toXDelta="30%"
android:duration="1000"
android:fillEnabled="true"/>
</set>
other_slide_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/decelerate_interpolator" >
<translate
android:fromXDelta="30%"
android:toXDelta="-70%"
android:duration="1000"/>
</set>
My Question : How I want to set right side panel to display and when click again it goes away. simply I my this code I want to remove the panel goes to full left see in the screenshot. the other part working fine.
ScreenShot :
Thanks in Advance.

I think I found the Solution. I am Creating the new Project.
Sliding.java
public class Sliding extends LinearLayout
{
private Paint innerPaint, borderPaint ;
public Sliding(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public Sliding(Context context) {
super(context);
init();
}
private void init() {
innerPaint = new Paint();
innerPaint.setARGB(0, 255, 255, 255); //gray
innerPaint.setAntiAlias(true);
borderPaint = new Paint();
borderPaint.setARGB(255, 255, 255, 255);
borderPaint.setAntiAlias(true);
borderPaint.setStyle(Paint.Style.STROKE);
borderPaint.setStrokeWidth(2);
}
public void setInnerPaint(Paint innerPaint) {
this.innerPaint = innerPaint;
}
public void setBorderPaint(Paint borderPaint) {
this.borderPaint = borderPaint;
}
#Override
protected void dispatchDraw(Canvas canvas) {
RectF drawRect = new RectF();
drawRect.set(0,0, getMeasuredWidth(), getMeasuredHeight());
canvas.drawRoundRect(drawRect, 5, 5, innerPaint);
canvas.drawRoundRect(drawRect, 5, 5, borderPaint);
super.dispatchDraw(canvas);
}
}
Sliding2Activity.java
public class Sliding2Activity extends Activity {
CheckBox c1,c2,c3;
int key=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sliding2);
final Sliding popup = (Sliding) findViewById(R.id.sliding1);
popup.setVisibility(View.GONE);
final FloatingActionButton btn=(FloatingActionButton)findViewById(R.id.show1);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
if (key == 0) {
key = 1;
popup.setVisibility(View.VISIBLE);
} else if (key == 1) {
key = 0;
popup.setVisibility(View.GONE);
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_sliding2, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
activity_sliding2.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:gravity="right"
android:orientation="horizontal">
<com.rey.material.widget.FloatingActionButton
android:id="#+id/show1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
style="#style/LightFABWaveColor"
android:layout_margin="8dp"
android:layout_gravity="bottom" />
<com.example.softeng.panel.Sliding
android:id="#+id/sliding1"
android:layout_width="250dp"
android:layout_height="match_parent"
android:background="#0072BA"
android:gravity="left"
android:orientation="vertical"
android:padding="1px">
<CheckBox
android:id="#+id/check1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option1"
android:textColor="#FFFFFF" />
<CheckBox
android:id="#+id/check2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option2"
android:textColor="#FFFFFF" />
<CheckBox
android:id="#+id/check3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option3"
android:textColor="#FFFFFF" />
</com.example.softeng.panel.Sliding>
</LinearLayout>
ScreenShot :
Normal screen when Activity is running.
When Click on FloatinActionButton. The layout is change.
When you click again the output is screen one.

Related

expand/collapse Animation Android half view

I would like to expand/collapse an ImageView but start from 50% picture to expand at 100%, collapse to 50% not under.
I already took a look at some popular questions and answers on SO but I didn't find how to manage only half. I also want to modify on the height of view, not the width.
What I tried :
public static void expand(final View v) {
v.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
final int targtetHeight = v.getMeasuredHeight();
v.getLayoutParams().height = 0;
v.setVisibility(View.VISIBLE);
Animation a = new Animation()
{
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
v.getLayoutParams().height = interpolatedTime == 1
? ViewGroup.LayoutParams.WRAP_CONTENT
: (int)(targtetHeight * interpolatedTime);
v.requestLayout();
}
#Override
public boolean willChangeBounds() {
return true;
}
};
a.setDuration((int)(targtetHeight / v.getContext().getResources().getDisplayMetrics().density));
v.startAnimation(a);
}
public static void collapse(final View v) {
final int initialHeight = v.getMeasuredHeight();
Animation a = new Animation() {
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
if (interpolatedTime == 1) {
v.setVisibility(View.VISIBLE);
} else {
v.getLayoutParams().height = initialHeight - (int) (initialHeight * interpolatedTime);
v.requestLayout();
}
}
#Override
public boolean willChangeBounds() {
return true;
}
};
a.setDuration((int) (initialHeight / v.getContext().getResources().getDisplayMetrics().density));
v.startAnimation(a);
}
as I said it's not what I want because it make disappeared totally and it change the width.
I also tried this snippet but there is no animation :
mImageDrawable = (ClipDrawable) pic.getDrawable();
mImageDrawable.setLevel(5000);//use set level to expand or collapse manually but no animation.
clip:
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:clipOrientation="vertical"
android:drawable="#drawable/test_pic"
android:gravity="top" />
Use Transition API which is available in support package (androidx). Just call TransitionManager.beginDelayedTransition then change height of view. TransitionManager will handle this changes and it will provide transition which will change imageView with animation.
scaleType of ImageView here is centerCrop thats why image scales when collapse and expand. Unfortunetly there is no "fill width and crop bottom" scaleType, so if you need it I think it can be done throught scaleType = matrix .
import androidx.appcompat.app.AppCompatActivity;
import androidx.transition.TransitionManager;
public class MainActivity extends AppCompatActivity {
private ImageView image;
private ViewGroup parent;
boolean collapse = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image = findViewById(R.id.image);
parent = findViewById(R.id.parent);
findViewById(R.id.btn).setOnClickListener(view -> {
collapse = !collapse;
collapse();
});
}
private void collapse() {
TransitionManager.beginDelayedTransition(parent);
//change layout params
int height = image.getHeight();
LayoutParams layoutParams = image.getLayoutParams();
layoutParams.height = !collapse ? height / 2 : height * 2;
image.requestLayout();
}
}
Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="#+id/btn"
android:text="start"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="300dp"
android:scaleType="centerCrop"
android:src="#drawable/qwe" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="random text"
android:layout_margin="8dp"/>
</LinearLayout>
UPDATE:
There is beginDelayedTransition(ViewGroup, Transtion) method. beginDelayedTransition(ViewGroup) by default use AutoTransition as transition.
So if you need handle start/end of transition you can do it like this:
AutoTransition transition = new AutoTransition();
transition.addListener(new TransitionListenerAdapter(){
#Override
public void onTransitionStart(#NonNull Transition transition) {
//TODO
}
#Override
public void onTransitionEnd(#NonNull Transition transition) {
//TODO
}
});
TransitionManager.beginDelayedTransition(parent, transition);

Android ActionBar menu with vertical (rotated) text items based on Custom Action Provider

I am adding a menu to an action bar item. The menu will contain vertical text for each item. What the menu contains is not important. I basically just want to create my own view that will pop up when I press an action bar item. So for the purposes of this question, you could imagine my view as a big black box.
The image on the right was made with Gimp. It is what I am trying to do, not what I have accomplished yet.
What I have tried
In order to update an old app with the Material Design theme, I've been going through all the lessons in the Android documentation for adding the app bar. Since my vertical text menu doesn't fit the common cases, I have to make a custom Action Provider. The documentation does not provide a full example for a custom action provider, though. The best I could find was this Stack Overflow answer.
The best I have been able to do (with a black View representing my future menu) is shown in the following image:
The star in the image above currently has the action provider. However, the custom view gets clipped off within the action bar. How do I make it float over everything? Also, I don't want it appearing until I click on the action bar item. Currently, though, it just shows right away.
Code
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// setup toolbar
Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(myToolbar);
...
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
// User chose the "Settings" item, show the app settings UI...
return true;
case R.id.action_favorite:
// User chose the "Favorite" action, mark the current item
// as a favorite...
return true;
default:
// If we got here, the user's action was not recognized.
// Invoke the superclass to handle it.
return super.onOptionsItemSelected(item);
}
}
...
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.v7.widget.Toolbar
android:id="#+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
...
menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_favorite"
android:icon="#drawable/ic_star_black_24dp"
android:title="#string/menu_favorites"
app:actionProviderClass="com.example.chimee.MyActionProvider"
app:showAsAction="ifRoom"/>
<item android:id="#+id/action_settings"
android:title="#string/menu_item_settings"
app:showAsAction="never"/>
</menu>
MyActionProvider.java
import android.content.Context;
import android.support.v4.view.ActionProvider;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
public class MyActionProvider extends ActionProvider {
private Context mContext;
public MyActionProvider(Context context) {
super(context);
mContext = context;
}
// for versions older than api 16
#Override
public View onCreateActionView() {
// Inflate the action provider to be shown on the action bar.
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
View providerView =
layoutInflater.inflate(R.layout.my_action_provider, null);
View myView =
(View) providerView.findViewById(R.id.blackView);
myView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("myTag", "black view was clicked");
}
});
return providerView;
}
#Override
public View onCreateActionView(MenuItem forItem) {
// TODO: don't just repeat all this code here from above.
// Inflate the action provider to be shown on the action bar.
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
View providerView =
layoutInflater.inflate(R.layout.my_action_provider, null);
View myView =
(View) providerView.findViewById(R.id.blackView);
myView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("myTag", "black view was clicked");
}
});
return providerView;
}
}
my_action_provider.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="?attr/actionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="?attr/actionBarItemBackground"
android:focusable="true" >
<View
android:id="#+id/blackView"
android:layout_width="200dp"
android:layout_height="150dp"
android:background="#000000" />
</LinearLayout>
I would be glad to see an example of any fully functioning custom action provider that shows a view outside of the action bar frame.
If You didn't find Custom Action Provider based solution, may be You want use Custom Toolbar & PopupWindow-based workaround which means:
1) create custom Toolbar with ImageButton as menu button and replace ActionBar with it (like in that post of Machado);
2) create PopupWindow with custom layout for menu items with vertical text;
3) add onClickListener to ImageButton from p.1 which show PopupWindow from p.2.
Layout of custom Toolbar (action_bar.xml) may be something like:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="fill_horizontal"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:background="#color/colorPrimary"
android:elevation="4dp"
android:layout_height="?attr/actionBarSize">
</android.support.v7.widget.Toolbar>
</RelativeLayout>
Layout of MainActivity (activity_main.xml) which use it:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="#+id/activity_main"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="0dp"
tools:context="<your_package_name>.MainActivity">
<include
android:id="#+id/tool_bar"
layout="#layout/action_bar"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:layout_marginStart="31dp"
android:layout_below="#+id/tool_bar"
android:layout_alignParentStart="true"
android:layout_marginTop="31dp"/>
</RelativeLayout>
ImageButton as "main popup menu" button described in main_menu.xml file this way (more in this post of ASH):
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/menu_button"
android:icon="#drawable/ic_more_vert"
android:title=""
app:showAsAction="always"
app:actionViewClass="android.widget.ImageButton"/>
</menu>
For vertical text of menu items You can use, for example, custom View like VerticalLabelView from this of kostmo:
public class VerticalLabelView extends View {
private TextPaint mTextPaint;
private String mText;
private int mAscent;
private Rect text_bounds = new Rect();
final static int DEFAULT_TEXT_SIZE = 15;
public VerticalLabelView(Context context) {
super(context);
initLabelView();
}
public VerticalLabelView(Context context, AttributeSet attrs) {
super(context, attrs);
initLabelView();
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.VerticalLabelView);
CharSequence s = a.getString(R.styleable.VerticalLabelView_text);
if (s != null) setText(s.toString());
setTextColor(a.getColor(R.styleable.VerticalLabelView_textColor, 0xFF000000));
int textSize = a.getDimensionPixelOffset(R.styleable.VerticalLabelView_textSize, 0);
if (textSize > 0) setTextSize(textSize);
a.recycle();
}
private final void initLabelView() {
mTextPaint = new TextPaint();
mTextPaint.setAntiAlias(true);
mTextPaint.setTextSize(DEFAULT_TEXT_SIZE);
mTextPaint.setColor(0xFF000000);
mTextPaint.setTextAlign(Align.CENTER);
setPadding(3, 3, 3, 3);
}
public void setText(String text) {
mText = text;
requestLayout();
invalidate();
}
public void setTextSize(int size) {
mTextPaint.setTextSize(size);
requestLayout();
invalidate();
}
public void setTextColor(int color) {
mTextPaint.setColor(color);
invalidate();
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mTextPaint.getTextBounds(mText, 0, mText.length(), text_bounds);
setMeasuredDimension(
measureWidth(widthMeasureSpec),
measureHeight(heightMeasureSpec));
}
private int measureWidth(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else {
// Measure the text
result = text_bounds.height() + getPaddingLeft() + getPaddingRight();
if (specMode == MeasureSpec.AT_MOST) {
// Respect AT_MOST value if that was what is called for by measureSpec
result = Math.min(result, specSize);
}
}
return result;
}
private int measureHeight(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
mAscent = (int) mTextPaint.ascent();
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else {
// Measure the text
result = text_bounds.width() + getPaddingTop() + getPaddingBottom();
if (specMode == MeasureSpec.AT_MOST) {
// Respect AT_MOST value if that was what is called for by measureSpec
result = Math.min(result, specSize);
}
}
return result;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float text_horizontally_centered_origin_x = getPaddingLeft() + text_bounds.width()/2f;
float text_horizontally_centered_origin_y = getPaddingTop() - mAscent;
canvas.translate(text_horizontally_centered_origin_y, text_horizontally_centered_origin_x);
canvas.rotate(-90);
canvas.drawText(mText, 0, 0, mTextPaint);
}
}
(NB: may be You need to customize paddings of VerticalLabelView: on line
result = text_bounds.height() + getPaddingLeft() + getPaddingRight() + 16;
add "+16" for better padding)
and attrs.xml for VerticalLabelView class:
<resources>
<declare-styleable name="VerticalLabelView">
<attr name="text" format="string" />
<attr name="textColor" format="color" />
<attr name="textSize" format="dimension" />
</declare-styleable>
</resources>
Layout for PopupWindow (menu_layout.xml) in this case might be like:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/menu_root"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="#dimen/activity_horizontal_margin">
<<your_package_name>.VerticalLabelView
android:id="#+id/menu_item1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:textSize="18sp"
android:layout_margin="16dp"
android:padding="4dp"
android:text="Vertical menu item 1"/>
<<your_package_name>.VerticalLabelView
android:id="#+id/menu_item2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:textSize="18sp"
android:layout_margin="16dp"
android:padding="4dp"
android:text="Vertical menu item 2"/>
<<your_package_name>.VerticalLabelView
android:id="#+id/menu_item3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:textSize="18sp"
android:layout_margin="16dp"
android:padding="4dp"
android:text="Vertical menu item 3"/>
<<your_package_name>.VerticalLabelView
android:id="#+id/menu_item4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:textSize="18sp"
android:layout_margin="16dp"
android:padding="4dp"
android:text="Vertical menu item 4"/>
</LinearLayout>
And MainActivity class can be like:
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private Toolbar mToolbar;
private int mToolbarTitleColor;
private ImageButton mMainMenuButton;
private int mActionBarSize;
private PopupWindow mPopupMenu;
private int mTextSize = 48;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TypedValue tv = new TypedValue();
if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
mActionBarSize = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
}
mToolbarTitleColor = Color.WHITE;
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mToolbar.setTitleTextColor(mToolbarTitleColor);
setSupportActionBar(mToolbar);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
Drawable menuIcon = ContextCompat.getDrawable(this, R.drawable.ic_more_vert);
menuIcon.setColorFilter(mToolbarTitleColor, PorterDuff.Mode.SRC_ATOP);
getMenuInflater().inflate(R.menu.main_menu, menu);
mMainMenuButton = (ImageButton) menu.findItem(R.id.menu_button).getActionView();
mMainMenuButton.setBackground(null);
mMainMenuButton.setImageDrawable(menuIcon);
mMainMenuButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mPopupMenu != null && mPopupMenu.isShowing()) {
mPopupMenu.dismiss();
}
mPopupMenu = createPopupMenu();
mPopupMenu.showAtLocation(v, Gravity.TOP | Gravity.RIGHT, 0, mActionBarSize);
}
});
return true;
}
public PopupWindow createPopupMenu() {
final PopupWindow popupWindow = new PopupWindow(this);
LayoutInflater inflater = getLayoutInflater();
View popupView = inflater.inflate(R.layout.menu_layout, null);
VerticalLabelView menuItem1 = (VerticalLabelView)popupView.findViewById(R.id.menu_item1);
menuItem1.setOnClickListener(mOnMenuItemClickListener);
menuItem1.setText("Vertical menu item 1");
menuItem1.setTextColor(Color.WHITE);
menuItem1.setTextSize(mTextSize);
VerticalLabelView menuItem2 = (VerticalLabelView)popupView.findViewById(R.id.menu_item2);
menuItem2.setOnClickListener(mOnMenuItemClickListener);
menuItem2.setText("Vertical menu item 2");
menuItem2.setTextColor(Color.WHITE);
menuItem2.setTextSize(mTextSize);
VerticalLabelView menuItem3 = (VerticalLabelView)popupView.findViewById(R.id.menu_item3);
menuItem3.setOnClickListener(mOnMenuItemClickListener);
menuItem3.setText("Vertical menu item 3");
menuItem3.setTextColor(Color.WHITE);
menuItem3.setTextSize(mTextSize);
VerticalLabelView menuItem4 = (VerticalLabelView)popupView.findViewById(R.id.menu_item4);
menuItem4.setOnClickListener(mOnMenuItemClickListener);
menuItem4.setText("Vertical menu item 4");
menuItem4.setTextColor(Color.WHITE);
menuItem4.setTextSize(mTextSize);
popupWindow.setFocusable(true);
popupWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
popupWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
popupWindow.setContentView(popupView);
return popupWindow;
}
private View.OnClickListener mOnMenuItemClickListener = new View.OnClickListener() {
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.menu_item1: {
Log.d(TAG, "menu_item1");
}
break;
case R.id.menu_item2: {
Log.d(TAG, "menu_item2");
}
break;
case R.id.menu_item3: {
Log.d(TAG, "menu_item3");
}
case R.id.menu_item4: {
Log.d(TAG, "menu_item4");
}
break;
default: {
}
}
if (mPopupMenu != null && mPopupMenu.isShowing()) {
mPopupMenu.dismiss();
}
}
};
}
Ultimatly, as result You should receive something like that:
P.S. Of course You need more elegant solution for createPopupMenu().

Intersecting two images in different Layouts

How it looks
I want to check intersection between ImageView to ImageView2 as LinearLayout slides towards ImageView2.
I used Rect but it is not working, ImageView2 Just passed throught it without getting intersect.
Please help me!!
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true" >
<ImageView
android:id="#+id/tile"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="#drawable/tile" />
<LinearLayout
android:id="#+id/l1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="100" >
<ImageView
android:id="#+id/b1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="50"
android:background="#000"
android:src="#drawable/b" />
<ImageView
android:id="#+id/b2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="70dp"
android:layout_weight="50"
android:background="#000"
android:src="#drawable/b" />
</LinearLayout>
#SuppressLint("NewApi")
public class MainActivity extends Activity {
Rect tileRect = new Rect();
Rect b1Rect = new Rect();
Rect b2Rect = new Rect();
ImageView tile,b1,b2;
RelativeLayout layout;
LinearLayout l1;
final Handler h = new Handler();
Boolean tileRight=false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
move();
}
private void init() {
// TODO Auto-generated method stub
b1 = (ImageView)findViewById(R.id.b1);
b2 = (ImageView)findViewById(R.id.b2);
tile = (ImageView)findViewById(R.id.tile);
layout = (RelativeLayout)findViewById(R.id.layout);
l1 = (LinearLayout)findViewById(R.id.l1);
tile.setX(320);
tile.setY(800);
l1.setVisibility(View.VISIBLE);
}
public void move()
{
final int delay = 45;
h.postDelayed(new Runnable()
{
#Override
public void run() {
// TODO Auto-generated method stub
layout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent event) {
// TODO Auto-generated method stub
if(event.getAction() == MotionEvent.ACTION_UP)
{
if(tileRight==true)
tileRight=false;
else
tileRight=true;
return true;
}
return false;
}
});
if(tileRight==true)
{
if(tile.getX()>600f)
{
tile.setX(tile.getX());
}
else{
tile.setX(tile.getX()+speedTile);
}
}
else{
if(tile.getX()<40f)
{
tile.setX(tile.getX());
}
else{
tile.setX(tile.getX()-speedTile);
}
}
tile.getHitRect(tileRect);
b1.getHitRect(b1Rect);
b2.getHitRect(b2Rect);
if(Rect.intersects(tileRect, b1Rect) || Rect.intersects(tileRect, b2Rect))
{
gameOver();
}
l1.setY(l1.getY()+10f);
h.postDelayed(this, delay);
}
},delay);
}
private void gameOver() {
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Android's View has getLocationOnScreen() method that shows absolute position of your view.
https://developer.android.com/reference/android/view/View.html#getLocationOnScreen(int[])
The issue occurs because view.getHitRect() is used before the layouts are inflated.
Any of the view's position or measurement APIs like getWidth(), getTop(), getRight() etc. will return 0 (getHitRect() initializes the Rect with (0,0,0,0)) in onCreate() or onResume() before the views are inflated.
In your case, it appears that the Handler's delay period executes the intersection logic earlier than view inflation.
You could post from the view and the run() method will execute after the view inflates and then obtain the view's measurement parameters or a Rect .
Here is an example:
public class MyTestActivity extends AppCompatActivity{
int mNumberOfViewsInitialized = 0;
ImageView mImageViewRight, mImageViewLeft;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sliding_image_activity);
mImageViewLeft = (ImageView) findViewById(R.id.image_view_left);
mImageViewRight = (ImageView) findViewById(R.id.image_view_right);
// calling method here will log that the views do not intersect
// which happens because they haven't been inflated yet.
// doViewsOverlap();
mImageViewLeft.post(new Runnable(){
#Override
public void run() {
mNumberOfViewsInitialized++;
intersectionLogic();
}
});
mImageViewRight.post(new Runnable(){
#Override
public void run() {
mNumberOfViewsInitialized++;
intersectionLogic();
}
});
}
private void intersectionLogic(){
/* the constant could be something else, depending
on the number of views you'd like to test intersection for*/
if(mNumberOfViewsInitialized == 2){
doViewsOverlap(mImageViewLeft,mImageViewRight);
}
}
private void doViewsOverlap(final View firstView, final View secondView){
Rect leftRect = new Rect();
firstView.getHitRect(leftRect);
Rect rightRect = new Rect();
secondView.getHitRect(rightRect);
if(Rect.intersects(leftRect,rightRect) || Rect.intersects(rightRect,leftRect))
Log.v("intersects","views intersect");
else
Log.v("intersects","views do not intersect");
}
}
I used a layout which does not animate / move the images, but the same issue should occur when the images are moved as well
<ImageView
android:id="#+id/image_view_left"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_alignParentLeft="true"
android:background="#android:color/holo_blue_dark"
android:src = "#mipmap/ic_launcher"/>
<ImageView
android:id="#+id/image_view_right"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_alignParentRight="true"
android:background="#android:color/holo_green_dark"
android:gravity="end"
android:src="#mipmap/ic_launcher"/>
Images contained in a RelativeLayout.
Here is a screenshot of the UI:
This problem is related to this: If I call getMeasuredWidth() or getWidth() for layout in onResume they return 0
Hope this helps.

Floating Action Button

I have been trying to use Floating Action Button. I tried to use some of the resources suggested on here and the links were great; however, I couldn't use alot of them because of problems with dependicies. I tried to fix it but it got more messed up. Long story short, I use the following code as a way to bypass dependicies in my bundle. I got the button to work; however, I couldn't figure out how to have options to appear when the button is clicked. I tried on clicklistener and other ways but I always got an error.
public class FloatingActionButton extends View {
Context context;
Paint mButtonPaint;
Paint mDrawablePaint;
Bitmap mBitmap;
boolean mHidden = false;
public FloatingActionButton(Context context) {
super(context);
this.context = context;
init(Color.WHITE);
}
public void init(int color) {
setWillNotDraw(false);
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
mButtonPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mButtonPaint.setColor(color);
mButtonPaint.setStyle(Paint.Style.FILL);
mButtonPaint.setShadowLayer(10.0f, 0.0f, 3.5f, Color.argb(100, 0, 0, 0));
mDrawablePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
invalidate();
}
#Override
protected void onDraw(Canvas canvas) {
setClickable(true);
canvas.drawCircle(getWidth() / 2, getHeight() / 2, (float) (getWidth() / 2.6), mButtonPaint);
canvas.drawBitmap(mBitmap, (getWidth() - mBitmap.getWidth()) / 2,
(getHeight() - mBitmap.getHeight()) / 2, mDrawablePaint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
setAlpha(1.0f);
} else if (event.getAction() == MotionEvent.ACTION_DOWN) {
setAlpha(0.6f);
}
return super.onTouchEvent(event);
}
public void setColor(int color) {
init(color);
}
public void setDrawable(Drawable drawable) {
mBitmap = ((BitmapDrawable) drawable).getBitmap();
invalidate();
}
public void hide() {
if (!mHidden) {
ObjectAnimator scaleX = ObjectAnimator.ofFloat(this, "scaleX", 1, 0);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(this, "scaleY", 1, 0);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(scaleX, scaleY);
animSetXY.setInterpolator(new AccelerateInterpolator());
animSetXY.setDuration(100);
animSetXY.start();
mHidden = true;
}
}
public void show() {
if (mHidden) {
ObjectAnimator scaleX = ObjectAnimator.ofFloat(this, "scaleX", 0, 1);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(this, "scaleY", 0, 1);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(scaleX, scaleY);
animSetXY.setInterpolator(new OvershootInterpolator());
animSetXY.setDuration(200);
animSetXY.start();
mHidden = false;
}
}
public boolean isHidden() {
return mHidden;
}
public static class Builder {
private FrameLayout.LayoutParams params;
private final Activity activity;
int gravity = Gravity.BOTTOM | Gravity.RIGHT; // default bottom right
Drawable drawable;
int color = Color.WHITE;
int size = 0;
float scale = 0;
/**
* Constructor using a context for this builder and the
* {#link com.williammora.openfeed.widgets.FloatingActionButton} it creates
* #param context
*/
public Builder(Activity context) {
scale = context.getResources().getDisplayMetrics().density;
// The calculation (value * scale + 0.5f) is a widely used to convert to dps to pixel
// units based on density scale
// see <a href="http://developer.android.com/guide/practices/screens_support.html">
// developer.android.com (Supporting Multiple Screen Sizes)</a>
size = (int) (72 * scale + 0.5f); // default size is 72dp by 72dp
params = new FrameLayout.LayoutParams(size, size);
params.gravity = gravity;
this.activity = context;
}
public Builder withGravity(int gravity) {
this.gravity = gravity;
return this;
}
public Builder withMargins(int left, int top, int right, int bottom) {
params.setMargins((int) (left * scale + 0.5f), (int) (top * scale + 0.5f),
(int) (right * scale + 0.5f), (int) (bottom * scale + 0.5f));
return this;
}
public Builder withDrawable(final Drawable drawable) {
this.drawable = drawable;
return this;
}
public Builder withColor(final int color) {
this.color = color;
return this;
}
public Builder withSize(int size) {
size = (int) (size * scale + 0.5f);
params = new FrameLayout.LayoutParams(size, size);
return this;
}
public FloatingActionButton create() {
final FloatingActionButton button = new FloatingActionButton(activity);
button.setColor(this.color);
button.setDrawable(this.drawable);
params.gravity = this.gravity;
ViewGroup root = (ViewGroup) activity.findViewById(android.R.id.content);
root.addView(button, params);
return button;
}
}
}
FloatingActionButton mFab = new FloatingActionButton.Builder(this)
.withColor(getResources().getColor(R.color.primaryColorDark))
.withDrawable(getResources().getDrawable(R.drawable.ic_launcher))
.withSize(72)
.withMargins(0, 0, 16, 16)
.create();
MainActivity
FloatingActionButton mFab = new FloatingActionButton.Builder(this)
.withColor(getResources().getColor(R.color.primaryColorDark))
.withDrawable(getResources().getDrawable(R.drawable.ic_launcher))
.withSize(72)
.withMargins(0, 0, 16, 16)
.create();
Just put compile 'com.android.support:design:22.2.1' in your module app dependencies.
In your xml:
<android.support.design.widget.FloatingActionButton
style="#style/<your_style>"
android:src="#drawable/<your_icon_src>"
app:layout_anchor="#id/<if using along with list put your listID here>"
app:layout_anchorGravity="bottom|right|end"
android:id="#+id/fab"
/>
In you java:
FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
There is no need to create FloatingActionButton by yourself now. The new com.android.support:design:23.0.1 can do that for you. Just follow the below procedure.
1.Add this line compile 'com.android.support:design:23.0.1' in dependencies in your build.gradle in Android Studio
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:design:23.0.1'
}
2.To create a FloatingActionButton using the following xml file.
<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:id="#+id/YourEventsLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--Add other elements here-->
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
android:layout_margin="16dp"
android:src="#drawable/ic_add_white_24dp"
app:elevation="6dp"
app:fabSize="normal"
app:pressedTranslationZ="12dp" />
</android.support.design.widget.CoordinatorLayout>
In MainActivity in onCreate method set setOnClickListener as follows
FloatingActionButton fab;
fab = (FloatingActionButton) getView().findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Do what you want here
}
});
This is how you create a floating action button.
build.gradle
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.0.0'
compile 'com.android.support:design:23.0.1'
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/viewOne"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.6"
android:background="#android:color/holo_blue_light"
android:orientation="horizontal"/>
<LinearLayout
android:id="#+id/viewTwo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.4"
android:background="#android:color/holo_orange_light"
android:orientation="horizontal"/>
</LinearLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:clickable="true"
android:src="#drawable/ic_done"
app:layout_anchor="#id/viewOne"
app:layout_anchorGravity="bottom|right|end"
app:backgroundTint="#FF0000"
app:rippleColor="#FFF" />
</android.support.design.widget.CoordinatorLayout>
</RelativeLayout>
MainActivity.java
package com.ahotbrew.floatingactionbutton;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FloatingActionButton FAB = (FloatingActionButton) findViewById(R.id.fab);
FAB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "Would you like a coffee?", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Hope that complete example helps someone.
The example is from http://www.ahotbrew.com/android-floating-action-button/
It also shows how to place the button in other locations if interested.
You don't have to create FAB now, its already available, just follow this Link
you need to add
<RelativeLayout
...
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.design.widget.FloatingActionButton
android:id="#+id/myFAB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_plus_sign"
app:elevation="4dp"
... />
</RelativeLayout>
and
FloatingActionButton myFab = (FloatingActionButton) myView.findViewById(R.id.myFAB);
myFab.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
doMyThing();
}
});
in code behind
For more detail follow :
FloatingActionButton example with Support Library

Animation Listener not working in FragmentActivity

I have a animation custom drawer menu class calling from 5 different activity , in 4 of them it works fine, but in one of them that i'm using FragmentActivity instead of Activity not working.
the behavior of menu in FragmentActivity is weird , in debug mode the code running well but it seems the drawer menu class have not UIthread, even when i'm using runOnUiThread.
I'm initialize the custom drawer class on onCreate() method of each Activity and in button click just call the DraverVisibility() method in Drawer class.
MainActivity class :
public class MainActivity extends FragmentActivity {
DraverMenu DraverMenu;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DraverMenu = new DraverMenu(this,
findViewById(android.R.id.content),
findViewById(R.id.draver_l1),
findViewById(R.id.activity_main_app_name),
findViewById(R.id.activity_main_app_icon),
findViewById(R.id.draver_change_language));
...
#Override
public boolean onCreatePanelMenu(int featureId, Menu menu) {
DraverMenu.DraverVisibility();
return false;
}
class DraverMenu :
public class DraverMenu {
private final Activity A;
private final int LEFT_DRAVER_MARGIN = 220;
private final int TOP_DRAVER_MARGIN = 45;
private final int OPEN_DRAVER_DURATION = 300;
private final int CLOSE_DRAVER_DURATION = 200;
private float left_px;
private float top_px;
private LinearLayout draver;
private View content;
public DraverMenu(Activity a, View content, View draver,
final View name, View icon, View language) {
this.A = a;
this.draver = (LinearLayout) draver;
left_px = ...;
top_px = ...;
FrameLayout.LayoutParams parm = (FrameLayout.LayoutParams) draver.getLayoutParams();
// if api<
parm.gravity = Gravity.TOP;
parm.leftMargin = -(int) left_px;
parm.topMargin = (int) top_px;
draver.setLayoutParams(parm);
this.content = content;
...
}
public void DraverVisibility() {
int vis = draver.getVisibility();
if (vis == View.VISIBLE) {
TranslateAnimation movetoleft = new TranslateAnimation(0, -left_px, 0, 0);
movetoleft.setDuration(CLOSE_DRAVER_DURATION);
movetoleft.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
FrameLayout.LayoutParams parm = (FrameLayout.LayoutParams)
draver.getLayoutParams();
// if api<
parm.gravity = Gravity.TOP;
parm.leftMargin = -(int) left_px;
parm.topMargin = (int) top_px;
draver.setLayoutParams(parm);
draver.setVisibility(View.INVISIBLE);
draver.setAnimation(null);
draver.invalidate();
content.setAnimation(null);
content.invalidate();
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
draver.startAnimation(movetoleft);
}
if (vis == View.INVISIBLE) {
InputMethodManager imm = (InputMethodManager) A.getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(draver.getWindowToken(), 0);
TranslateAnimation movetoRight = new TranslateAnimation(0, left_px, 0, 0);
movetoRight.setDuration(OPEN_DRAVER_DURATION);
movetoRight.setFillEnabled(true);
movetoRight.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
draver.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationEnd(Animation animation) {
FrameLayout.LayoutParams parm = (FrameLayout.LayoutParams) draver.getLayoutParams();
// if api<
parm.gravity = Gravity.TOP;
parm.leftMargin = 0; //-(int)left_px;
parm.topMargin = (int) top_px;
draver.setLayoutParams(parm);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
draver.startAnimation(movetoRight);
}
}
}
The XML of DrawerMenu is inclode in MainActivity XML
DrawerMenu XML :
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:orientation="vertical"
android:layout_width="220dp"
android:layout_height="match_parent"
android:background="#cc000000"
android:visibility="invisible"
android:id="#id/draver_l1"
android:layout_marginTop="30dp"
android:layout_gravity="center_vertical"
android:gravity="center">
<TextView
android:layout_width="130dp"
android:layout_height="130dp"
android:id="#+id/textView" android:background="#drawable/ic_launcher"/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/draver_language_button_text"
android:id="#id/draver_change_language"/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/draver_software_info"
android:id="#id/draver_button_2"/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/draver_contact_us"
android:id="#id/draver_button_3"/>
<TextView
android:layout_width="130dp"
android:layout_height="130dp"
android:id="#+id/textView1" android:background="#drawable/barcodeqr"/>
</LinearLayout>
any suggestion ?

Categories

Resources