Slide up and Down animation for Fragment transaction in Android - java

I am developing an app in Android. I am using a flow to take information form the user. To build the flow I am using few fragments. There are five steps and I am using five fragments. I am using another fragment to show the previous records he saved using list view. In my activity I am using a button named Expand. The button Expand is used to show the previous records using fragment. When the user clicks on the button Expand the fragment will take place and the Expand button text will be set to Hide. When the button text is Hide, if the user clicks on the button again the fragment will be removed from the stack and the previous fragment added to the back stack will be shown.
For example let us assume that I have five fragments named FragmentA, FragmentB, FragmentC, FragmentD, FragmentE and another fragment named ProjectRowsFragment which will be used to show the records previously saved in a ListView on the click event of the button named Expand.
Let us assume that the user is in FragmentC and he clicked on the Expand button. What will happen is that FragmentC will be replaced and ProjectRowsFragment will be added. If the user clicks on the button again the ProjectRowsFragment will be replaced and the FragmentC will come in from back stack. If it was FragmentD then it will be replaced and ProjectRowsFragment will be added and if user clicks on the button again ProjectRowsFragment will be replaced and FragmentD will come in from back stack.
I have done with the transactions.
What I want is that I want animation to be added while the ProjectRowsFragment (The fragment I am using to show the records) is shown and replaced. When it is shown it will slide down from the top and then when it is removed from the back stack it will slide up.
After trying a lot I accomplished the slide down effect, but how can I get the slide up animation.
Here is my codes.
fragmentManager = getFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(R.animator.slide_in_from_top, 0, R.animator.slide_in_from_bottom, 0);
fragmentTransaction.replace(R.id.fragment_container, ProjectRowsFragment.newInstance(this.projectId));
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
projectRowsExpanded = true;
slide_in_from_top.xml file is
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true" >
<objectAnimator
android:duration="600"
android:propertyName="y"
android:valueFrom="-1280"
android:valueTo="0"
android:valueType="floatType" />
</set>
Here i have three images to visualize
Initial Step
If the user clicks on the button indicated a list will be placed.
If the user clicks again in the indicated button.

Instead of applying custom animations to fragment, you can add animation to your FrameLayout, by passing your fragment container view to following functions to expand and collapse:
FrameLayout v = (FrameLayout) findViewById(R.id.fragment_container);
expand(v); //To Expand
collapse(v); //To Collapse
public static void expand(final View v) {
v.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
final int targetHeight = v.getMeasuredHeight();
v.getLayoutParams().height = 1;
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) (targetHeight * interpolatedTime);
v.requestLayout();
}
#Override
public boolean willChangeBounds() {
return true;
}
};
a.setDuration((int) (targetHeight / 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.GONE);
} 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);
}

Related

Removing background on drawable used in floating action button when clicked (Android Studio)

I am using a Github library (https://github.com/oguzbilgener/CircularFloatingActionMenu) to create a circular floating action menu programmatically. Using drawables I have added a menu and an exit icon to the floating action menu and I want to remove the square border around the menu and exit icons that appear when the menu is clicked. I have tried things like programmatically setting the background of the button to be null or changing it's 'alpha' value, neither of which has the desired effect.
There are other questions posted asking this but they are all creating the menu/button using XML while I'm doing it programmatically using Java. Is there any way to remove the border (and if possible fill the whole menu button with the icons rather than have it enclosed inside)? Below I have inserted the code I'm using from the library for convenience:
// Create our Floating Action Button
final ImageView fabIconNew = new ImageView(getActivity());
/* Set the icon in the center of the Floating Action Button
Old Deprecated way to get drawable -> getResources().getDrawable(R.drawable.ic_action_new_light)
Instead, use -> getApplicationContext(), R.drawable.ic_action_new_light)
*/
fabIconNew.setImageDrawable(ContextCompat.getDrawable(getActivity().getApplicationContext(), R.drawable.menu_icon));
final FloatingActionButton rightLowerButton = new FloatingActionButton.Builder(getActivity())
.setContentView(fabIconNew)
.setPosition(FloatingActionButton.POSITION_BOTTOM_RIGHT)
.build();
// Create your menu items which are also Floating Action Buttons
SubActionButton.Builder rLSubBuilder = new SubActionButton.Builder(getActivity());
// Create an image view for each menu item
ImageView menuOption1 = new ImageView(getActivity());
ImageView menuOption2 = new ImageView(getActivity());
// Set the ico/*rea*/n for each menu item
menuOption1.setImageDrawable(ContextCompat.getDrawable(getActivity().getApplicationContext(), R.drawable.button_sub_action));
menuOption2.setImageDrawable(ContextCompat.getDrawable(getActivity().getApplicationContext(), R.drawable.button_sub_action_selector));
// Build the menu with default options: 90 degrees, 72dp radius.
// Set 4 default SubActionButtons
final FloatingActionMenu rightLowerMenu = new FloatingActionMenu.Builder(getActivity())
.addSubActionView(rLSubBuilder.setContentView(menuOption1).build())
.addSubActionView(rLSubBuilder.setContentView(menuOption2).build())
.attachTo(rightLowerButton)
//.setStartAngle(360)
.build();
// Listen for menu open and close events to animate the button content view
rightLowerMenu.setStateChangeListener(new FloatingActionMenu.MenuStateChangeListener() {
#Override
public void onMenuOpened(FloatingActionMenu menu) {
// Rotate the icon of rightLowerButton 45 degrees clockwise
// fabIconNew.setRotation(0);
fabIconNew.setImageDrawable(ContextCompat.getDrawable(getActivity().getApplicationContext(), R.drawable.exit_icon));
PropertyValuesHolder pvhR = PropertyValuesHolder.ofFloat(View.ROTATION, 0);
ObjectAnimator animation = ObjectAnimator.ofPropertyValuesHolder(fabIconNew, pvhR);
animation.start();
}
#Override
public void onMenuClosed(FloatingActionMenu menu) {
// Rotate the icon of rightLowerButton 45 degrees counter-clockwise
// fabIconNew.setRotation(45);
fabIconNew.setImageDrawable(ContextCompat.getDrawable(getActivity().getApplicationContext(), R.drawable.menu_icon));
PropertyValuesHolder pvhR = PropertyValuesHolder.ofFloat(View.ROTATION, 0);
ObjectAnimator animation = ObjectAnimator.ofPropertyValuesHolder(fabIconNew, pvhR);
animation.start();
}
});
// OnClickListeners for each menu item
menuOption1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity().getApplicationContext(), "Option 1", Toast.LENGTH_SHORT).show();
/*
Could also go to an Intent or perform whatever action you want.
To go to another Activity, you would use something like:
Intent goToActivity = new Intent(getApplicationContext(), Name_Of_Activity.class)
startActivity(goToActivity);
*/
}
});
menuOption2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity().getApplicationContext(), "Option 2", Toast.LENGTH_SHORT).show();
NavHostFragment.findNavController(FirstFragment.this)
.navigate(R.id.action_FirstFragment_to_SecondFragment);
rightLowerMenu.close(true);
rightLowerButton.setVisibility(View.GONE);
}
});

Destroy a button that was added programatically multiple times on its click

The title may sound confusing I know, I 'm adding a view everytime I click on a button, composed by a textview and a button. I'm setting every added view an ID with simply view.setID(++i) and every added button (inside the views) an ID simply with button.setID(++n), n starting at 1000, since I won't have more than 1000 added views.
Here's what I got:
public class MainActivity extends AppCompatActivity {
GridLayout gridLayout;
static int i;
static int n = 1000;
private Button theButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridLayout = (GridLayout)findViewById(R.id.gamehistory);
Button b = (Button)findViewById(R.id.Button01);
b.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
theButton = new Button(MainActivity.this);
TextView theText = new TextView(MainActivity.this);
theText.setGravity(Gravity.CENTER_HORIZONTAL);
LinearLayout theLayout = new LinearLayout(MainActivity.this);
theLayout.setOrientation(LinearLayout.VERTICAL);
theLayout.setBackgroundColor(Color.parseColor("#8BAAC3"));
theLayout.setId(++i);
theButton.setId(++n);
theButton.setText(theButton.getId() + "");
theText.setText(theLayout.getId() + "");
theLayout.addView(theButton);
theLayout.addView(theText);
gridLayout.addView(theLayout);
GridLayout.LayoutParams lp = (GridLayout.LayoutParams) theLayout.getLayoutParams();
lp.setMargins(10, 10, 10, 10);
}
});
What I need is when I click on a button that was created, the correspondent view is destroyed, and the next views take one step back feeling the gap in the parent which is a GridLayout
Add this where you are adding views to GridLayout -
theLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
gridLayout.removeView(theLayout);
}
});
theButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
gridLayout.removeView(theLayout);
}
});
For this , you need to make theLayout final
final LinearLayout theLayout = new LinearLayout(LauncherActivity.this);
The simplest method would be.
View v = gridLayout.findViewById(<some id>);
gridLayout.removeView(v);
However it seems like you may want to consider using a RecyclerView. You can add/remove items from the Adapter and the views will be updated for you.
EDIT
When using A RecyclerView you have to specify two essential components.
RecyclerAdapter - This converts data into views (rows, cards, cells, ect.)
LayoutManger - Most common are LinearLayoutManger and GridLayoutManager which define how the views from the adapter are presented out in relation to one another, and handle scrolling.
There are a few more option additions you can can use if needed.
ItemDecoration - define backgrounds, or overlays for cells. (E.G. draw a gray background for every other view in a list)
ItemTouchHelper - does most of the heavy lifting for swipe (e.g. swipe to delete) and drag (e.g. drag to re-arrange) operations.
I would highly suggest getting familiar with the RecyclerView it should be your goto component when you need to display a list of items on the screen.

onClick not doing anything... "ViewPostImeInputStage ACTION_DOWN"

I'm working on an app that uses PayPal. I need to use the MPL, as opposed to the SDK, because my app needs to be able to implement third-party payments. I've followed various tutorials and created the code below. I don't get any compiler errors, and no log cat error, but when I run it and click on the "Pay with PayPal" button, nothing happens. Instead, I get ViewPostImeInputStage ACTION_DOWN when I click on the button or anywhere on the screen.
I have no idea why. Please help!
public class MainActivity extends Activity implements View.OnClickListener {
private CheckoutButton launchPayPalButton;
final static public int PAYPAL_BUTTON_ID = 10001;
private double _theSubtotal;
private double _taxAmount;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initLibrary();
showPayPalButton();
}
private void showPayPalButton() {
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setOrientation(LinearLayout.VERTICAL);
ViewGroup.LayoutParams linearLayoutParam = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
setContentView(linearLayout, linearLayoutParam);
LayoutParams lpView = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
// Generate the PayPal checkout button and save it for later use
PayPal pp = PayPal.getInstance();
launchPayPalButton = pp.getCheckoutButton(this, PayPal.BUTTON_194x37, CheckoutButton.TEXT_PAY);
// The OnClick listener for the checkout button
launchPayPalButton.setOnClickListener(this);
// Add the listener to the layout
launchPayPalButton.setLayoutParams(lpView);
launchPayPalButton.setId(PAYPAL_BUTTON_ID);
linearLayout.addView(launchPayPalButton);
}
public void PayPalButtonClick(View arg0) {
PayPalPayment newPayment = new PayPalPayment();
newPayment.setSubtotal(new BigDecimal(_theSubtotal));
newPayment.setCurrencyType("USD");
newPayment.setRecipient("my#email.com");
newPayment.setMerchantName("My Company");
Intent paypalIntent = PayPal.getInstance().checkout(newPayment, this);
this.startActivityForResult(paypalIntent, 2);
}
public void initLibrary() {
PayPal pp = PayPal.getInstance();
if (pp == null) { // Test to see if the library is already initialized
// This main initialization call takes your Context, AppID, and target server
pp = PayPal.initWithAppID(this, "APP-80W284485P519543T", PayPal.ENV_NONE);
// Required settings:
// Set the language for the library
pp.setLanguage("en_US");
// Some Optional settings:
// Sets who pays any transaction fees. Possible values are:
// FEEPAYER_SENDER, FEEPAYER_PRIMARYRECEIVER, FEEPAYER_EACHRECEIVER, and FEEPAYER_SECONDARYONLY
pp.setFeesPayer(PayPal.FEEPAYER_EACHRECEIVER);
// true = transaction requires shipping
pp.setShippingEnabled(false);
}
}
#Override
public void onClick(View arg0){
PayPalButtonClick(arg0);
}
}
Probably because you haven't set the content view after super.oncreate() and since you're registering your activity as the on click listener, its responding to clicks from anywhere on the screen instead of just the button.
EDIT
Add an on click listener to the button like this
paypalButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) { PayPalButtonClick(arg0); }
});
and remove the implementation of the OnClickListener from your activity
ViewPostImeInputStage ACTION_DOWN is basically a condition when your layout is rejected and you are no longer be able to click on any clickable items.The solution for this is simple, just wrap your layout contents with a parent.
for ex:
if you have the xml with format as:
<LinearLayout <---root layout
..... contents here
</LinearLayout> <-- root layout end
change to
<FrameLayout <---root layout
<LinearLayout <-- parent wrap start
...
<!-- your content -->
</LinearLayout> <-- parent wrap end
</FrameLayout> <-- root layout end
for more information, you might wana consider reading this

can't select any element on infalted layout

I have an inflated layout that appears when I select a GeoPoint, the inflated layout has a button on it and I can't seem to be able to click the button and have spent hours trying to figure out why and have done this to no avail. Below shows the code where the inflated layout is invoked and also the onClick for the button is shown.
public View getInfoContents(Marker arg0) {
View v = getLayoutInflater().inflate(R.layout.place_detail, null);
String pos = arg0.getSnippet(); //get index of the marker data
Button accept = (Button) v.findViewById(R.id.button3);
accept.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Toast.makeText(getApplicationContext(),"HAPPY MAN", Toast.LENGTH_LONG).show();
}
});
try{
int ipos = Integer.parseInt(pos);
PlaceData data = mListPlaceData.get(ipos); //get the data by index
((TextView)v.findViewById(R.id.txtName)).setText(data.name); //show name of the place
((TextView)v.findViewById(R.id.txtHours)).setText("Hours: "+data.hours); //show hours of the place
((TextView)v.findViewById(R.id.txtCountry)).setText("Country: "+data.country); //show country of the place
((TextView)v.findViewById(R.id.txtAddress)).setText("Address: "+data.address); //show address of the place
((TextView)v.findViewById(R.id.txtPostCode)).setText("Postcode: "+ data.postcode); //show postcode of the place
}catch(Exception e){
}
return v;
}
});
}
The info window that is drawn is not a live view. The view is rendered as an image (using View.draw(Canvas)) at the time it is returned. This means that any subsequent changes to the view will not be reflected by the info window on the map. To update the info window later (for example, after an image has loaded), call showInfoWindow(). Furthermore, the info window will not respect any of the interactivity typical for a normal view such as touch or gesture events. However you can listen to a generic click event on the whole info window as described in the section below.
Source:https://developers.google.com/maps/documentation/android/infowindows

How can I make a drop down hidden menu

I want to make a drop down menu, like a status menu, that is hidden when the activity starts, and when it's pressed or slid it opens like the image below..
http://i.stack.imgur.com/jeq5z.png
My layout currently has a RelativeLayout for the top bar and a ScrollView for the text.. between those, i'd like to put the menu..
I'm not doing this app on phonegap or anything like that, just java and xml..
Thanks in advance
Edit:
Thank you all for your help! I end up doing a FrameLayout that was set off the screen with the translationY and then, when clicked, just slide up and down.. Here's the snipped.. I'll just leave it here in case someone else needs it.
on layout.xml
<FrameLayout
android:id="#+id/layout_FrameLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#00ffffff" >
<!-- stuf -->
</FrameLayout>
on activity.java
private FrameLayout statusDrawer = null;
private int statusDrawerHeight; // height of the FrameLayout (generated automatically)
private int statusDrawerDragButtonHeight = 30 + 5; //height of the DragButton + height of the border
private boolean statusDrawerOpened = false;
private int statusDrawerDuration = 750; //time in milliseconds
private TimeInterpolator interpolator = null; //type of animation see#developer.android.com/reference/android/animation/TimeInterpolator.html
#Override
protected void onCreated(Bundle savedInstanceState){
statusDrawer = (FrameLayout) findViewById(R.id.layout_FrameLayout);
interpolator = new AccelerateDecelerateInterpolator();
statusDrawer.post(new Runnable() {
#Override
public void run() {
statusDrawerHeight = statusDrawer.getHeight();
statusDrawer.setTranslationY(-statusDrawerHeight+statusDrawerDragButtonHeight);
}
});
statusDrawer.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v){
if(statusDrawerOpened) {
statusDrawer.animate()
.translationY(-statusDrawerHeight+statusDrawerDragButtonHeight)
.setDuration(statusDrawerDuration)
.setInterpolator(interpolator)
.start();
} else {
statusDrawer.animate()
.translationY(0)
.setDuration(statusDrawerDuration)
.setInterpolator(interpolator)
.start();
}
statusDrawerOpened = !statusDrawerOpened;
}
});
}
Use a FrameLayout as the root layout. Add the drop menu layout as in the right side of your picture. Call
menuView.setTranslationY(-view.getHeight);
on this view to initially hide the drop down menu when the activity is started. Make sure menuView only refers to the drop down view part without the small tab button. When the user touches the tab animate translationY to 0 so that the layout will slide down
ObjectAnimator.ofFloat(dropDownView, "translationY", -view.getHeight, 0).setDuration(200).start();
whereby dropDownView refers to the complete drop down menu.
Using ObjectAnimator requires API level 11. If you need to support older API levels, use http://developer.android.com/reference/android/view/animation/TranslateAnimation.html (which has some down sides).
If you instead want add a sliding effect, e.g. the sliding menu is moving with together with the finger, install a OnTouchListener:
dropDownTab.setOnTouchListener(new OnTouchListener() {
public void onTouch(View v, MotionEvent e) {
// Make the drop down menu finger follow the finger position.
// Use again dropDownView.setTranslationY(...) to move the view.
// If the drop down menu has been dragged a certain distance, make it move out by itself using the animation as above.
}
});

Categories

Resources