Simple and practical Android UI Micro Blog Dynamic Point-praise effect _android

Source: Internet
Author: User
Tags event listener prepare static class

Speaking of space dynamics, micro-bo the point of praise effect, the Internet is also very rampant, a variety of implementation and effect of a large pile. And the detailed implementation of the part, the story is also uneven, on the other hand, it is estimated that many heroes also shrugged off, feel that there is no need to write a separate opening and explain it. After all, two view and some simple animation effects.
If I were to say this alone, I would not be willing to take this effort. Although oneself is very vegetable, can also not be willing to too dish. So occasionally see some good things, can extend learn to write down, I am still very willing to take out to use, incidentally show a show force lattice what.
Do not pull too much, first of all, to say that the effect of a point of praise today to use the two good points:

checkable is used to extend view to implement checked state switching
Androidviewanimations based on the Nineoldandroids package of Android animation Simple class library. How simple is it, like this?

Animhelper.with (New Pulseanimator ()). Duration (1000). Playon (ImageView);
Function: Use Pulseanimator This animation effect on ImageView, play one second.

Of course, from the point of view of the realization of this library, if only the use of google/Baidu a lot of.

Combine the first two rich text folding expansion, plus our point of view to make a demo integration effect map:

1. From the realization to see the doorway

In fact, from the effect to see nothing more than a click to switch pictures, and add some simple animation effect, it is really not difficult. Here is the introduction of two good new content, the use of the right when novice taste.

1.1 Checkable Interface Implementation Checkedimageview

The system itself provides an interface for android.widget.Checkable to enable us to inherit the status of the check and cancel of the view. Look at this class:

Public interface Checkable {

 /**
 * Set View's selected state
 *
 /void setchecked (Boolean checked);

 /**
 * The current view is selected
 *
 /Boolean ischecked ();

 /**
 * Change View's selected state to the opposite state
 /void Toggle ();
}

This interface is usually used to help us quickly implement the optional effect of view, increasing the selection and cancellation of both States and switching methods. In addition, in order to facilitate the view when the state changes quickly to see the effect (more background or pictures), we can directly through the selector control of the picture, and its own does not automatically change the drawable state, so it is necessary to rewrite the drawablestatechanged
Method. Let's take the example of defining a generic Checkedimageview:

public class Checkedimageview extends ImageView implements checkable{protected Boolean ischecked;//selected state protected Eckedchangelistener oncheckedchangelistener;//State Change event listener public static final int[] Checked_state_set = {Android.

 R.attr.state_checked};
 Public Checkedimageview {Super (context);
 Initialize ();
 Public Checkedimageview (context, AttributeSet attrs) {Super (context, attrs);
 Initialize ();
 private void Initialize () {ischecked = false;
 @Override public boolean ischecked () {return ischecked; @Override public void setchecked (Boolean ischecked) {if (this.ischecked!= ischecked) {this.ischecked = Ischecke
  D

  Refreshdrawablestate ();
  if (Oncheckedchangelistener!= null) {oncheckedchangelistener.oncheckedchanged (this, ischecked);
 @Override public void Toggle () {//Change state setchecked (!ischecked); }///initial drawablestate when adding a checked_state,imageview itself is not in this state @Override public int[] Oncreatedrawablestate (int extraspace) {int[] states = Super.oncreatedrawablestate (Extraspace + 1);
 if (ischecked ()) {mergedrawablestates (states, Checked_state_set);
 return states; //When the view's selected state is changed to notify ImageView to change the background or content, this view automatically selects the picture that matches the current state in the drawable state set @Override protected void
 Drawablestatechanged () {super.drawablestatechanged ();
 drawable drawable = getdrawable ();
  if (drawable!= null) {int[] mydrawablestate = Getdrawablestate ();
  Drawable.setstate (mydrawablestate);
 Invalidate (); }//Set state change listener event public void Setoncheckedchangelistener (Oncheckedchangelistener oncheckedchangelistener) {This.onche
 Ckedchangelistener = Oncheckedchangelistener; The Listener interface triggers the event public static interface Oncheckedchangelistener {public void oncheckedchanged (Checkedimageview
 Checkedimgeview, Boolean ischecked);
 }
}

This is a generic can be selected ImageView, when clicked is selected, click again to cancel. and its background/content will change. For example, the following image shows the effect:

  

From the code point of view, we do not directly define when the view click, call SetImage () or SetBackground () to change the content, but by using the view itself drawablestate to draw and change, to find the corresponding match with the picture, And these states correspond to the picture, all in advance in the selector configuration. About selector here does not do introduction, oneself consult study.

Since the mention of selector, incidentally mentioned before encountered the pit, about his matching principle. such as the bottom of such a selector:

<?xml version= "1.0" encoding= "Utf-8"?> <selector xmlns:android=
"http://schemas.android.com/apk/res/" Android >
 <item android:state_pressed= "true" android:drawable= "@drawable/icon_pressed" ></item >
 <item android:state_checked= "true" android:drawable= "@drawable/icon_checked" ></item>
 <item android:drawable= "@drawable/icon_normal" ></item>
</selector>

When view has the top two states (such as state_pressed and state_checked), view takes precedence over the first state of the picture (icon_pressed). This is because it is searched in order from top to bottom, and when the first state is found to match the row that he defined, the picture of the line is displayed as a priority. So when we take the last line

< item android:drawable= "@drawable/icon_normal" ></item>

On the first line, Icon_normal is displayed regardless of whether the state is selected or pressed. Beginners must pay attention to, I originally because of this reason spent a lot of time to find out why.

Back to our point of praise realization. Here is the realization of the point of view Praiseview contains a checkedimageview and a TextView, after a bit of praise, ImageView will magnify the retraction and eject a TextView "+1" animation effect.

The public class Praiseview extends Framelayout implements checkable{//also inherits checkable protected Onpraischeckedlistener Prais
 Echeckedlistener; protected Checkedimageview ImageView; Point praise picture protected TextView TextView;

 +1 protected int padding;
 Public Praiseview {Super (context);
 Initalize ();
 Public Praiseview (context, AttributeSet attrs) {Super (context, attrs);
 Initalize ();
 } protected void Initalize () {setclickable (true);
 ImageView = new Checkedimageview (GetContext ());
 Imageview.setimageresource (R.drawable.blog_praise_selector); Framelayout.layoutparams FLP = new Layoutparams (FrameLayout.LayoutParams.WRAP_CONTENT,
 Framelayout.layoutparams.wrap_content,gravity.center);

 AddView (ImageView, FLP);
 TextView = new TextView (GetContext ());
 Textview.settextsize (10);
 Textview.settext ("+1");
 Textview.settextcolor (Color.parsecolor ("#A24040"));
 Textview.setgravity (Gravity.center);
 AddView (TextView, FLP);
 Textview.setvisibility (View.gone); }

 @Override public boolean PerformClick () {checkchange ();
 return Super.performclick ();
 @Override public void Toggle () {checkchange ();
 } public void Setchecked (Boolean ischeacked) {imageview.setchecked (ischeacked);
 public void Checkchange () {//Click Toggle State if (imageview.ischecked) {imageview.setchecked (false);
  else {imageview.setchecked (true);
  Textview.setvisibility (view.visible);
  Enlarge the animation Animhelper.with (New Pulseanimator ()). Duration (1000). Playon (ImageView);
 Fluttering "+1" animation Animhelper.with (New Slideoutupanimator ()). Duration (1000). Playon (TextView);
 }//Call Point-praise event if (Praisecheckedlistener!= null) {praisecheckedlistener.onpraischecked (imageview.ischecked);
 } public boolean ischecked () {return imageview.ischecked; } public void Setonpraischeckedlistener (Onpraischeckedlistener praisecheckedlistener) {This.praisecheckedlistener = P
 Raisecheckedlistener;
 public interface onpraischeckedlistener{void Onpraischecked (Boolean ischecked);
 }
}

Too custom view probably so much, checkable this small convenient class, do not know you will use. As for the top two animation effects set:

Animhelper.with (New Pulseanimator ()). Duration (1000). Playon (ImageView);
Animhelper.with (New Slideoutupanimator ()). Duration (1000). Playon (TextView);
The feeling package is quite concise and practical, so it is necessary to study and analyze.

1.2 The encapsulation and fast frame of the animation library

Mention of animation, Android itself with the animation class animation has been able to support 3.0 and more, although also done a good package, but do a complex animation is not enough like the top as simple. On the compatibility aspect of animation, Daniel Jake Wharton on GitHub also made a set of animation open Source Library Nineoldandroids, the effect is very good and support the previous version of Level 3, indeed very commendable. On this basis, there are many masters and do a two of encapsulation, to achieve a complex animation, while ensuring convenient and concise, but also more versatile and scalable. The animation we use here is a simple encapsulation.
For example, to use an animation like xxanimator on a Xxview, it lasts duration seconds. That's one line of code:

Animhelper.with (New Slideoutupanimator ()). Duration (1000). Playon (TextView);
Take a look at the concrete implementation of the viewanimations based on Nineoldandroids.

1. First define a basic animation effect class Baseviewanimator

This baseviewanimator animation class uses an animated set of Animatorset, wraps it into a single animation similar usage, and defines an abstract method prepare ():

 Public abstract class Baseviewanimator {public static final long DURATION = 1000;
 Private Animatorset Manimatorset;

 Private long mduration = DURATION;
 {manimatorset = new animatorset ();

 protected abstract void Prepare (View target);
 Public Baseviewanimator settarget (View target) {reset (target);
 Prepare (target);
 return this;
 public void animate () {start (); /** * Reset the view to default status * * @param target */public void reset (view target) {Viewhelper.setalpha
 (target, 1);
 Viewhelper.setscalex (target, 1);
 Viewhelper.setscaley (target, 1);
 Viewhelper.settranslationx (target, 0);
 Viewhelper.settranslationy (target, 0);
 Viewhelper.setrotation (target, 0);
 Viewhelper.setrotationy (target, 0);
 Viewhelper.setrotationx (target, 0);
 Viewhelper.setpivotx (Target, target.getmeasuredwidth ()/2.0f);
 Viewhelper.setpivoty (Target, target.getmeasuredheight ()/2.0f); }/** * start to animate */public void start () {Manimatorset.setduration (Mduration);
 Manimatorset.start ();
 Public Baseviewanimator setduration (long duration) {mduration = duration;
 return this;
 Public Baseviewanimator Setstartdelay (long delay) {getanimatoragent (). Setstartdelay (delay);
 return this;
 Public long Getstartdelay () {return manimatorset.getstartdelay ();
 Public Baseviewanimator Addanimatorlistener (Animatorlistener l) {Manimatorset.addlistener (L);
 return this;
 public void Cancel () {manimatorset.cancel ();
 public boolean isrunning () {return manimatorset.isrunning ();
 public Boolean isstarted () {return manimatorset.isstarted ();
 public void Removeanimatorlistener (Animatorlistener l) {Manimatorset.removelistener (L);
 public void Removealllistener () {manimatorset.removealllisteners ();
 Public Baseviewanimator Setinterpolator (interpolator interpolator) {manimatorset.setinterpolator (Interpolator);
 return this;
 Public long getduration () {return mduration; } public Animatorset GetanimatoRagent () {return manimatorset;
 }

}

The complex animation effect base class Baseviewanimator uses a Animatorset collection to add various animations and binds to the target TargetView, using prepare (View target) Abstract method for its subclasses to achieve specific animation effects.

2). Second, based on this class to achieve our various animation effects Xxanimator

When we want to implement specific animation effects, we can directly inherit this class and implement the Prepaer method. For example, this defines the slideoutupanimator and zooming back animation pulseanimator

/**
* Disappear (float + 1) * * * Public
class Slideoutupanimator extends Baseviewanimator {
 @Override
 public void prepare (View target) {
 ViewGroup parent = (ViewGroup) target.getparent ();
 Getanimatoragent (). Playtogether (
  objectanimator.offloat (target, "Alpha", 1, 0),
  objectanimator.offloat ( Target, "Translationy", 0,-parent.getheight ()/2)
 );
 }

/**
* Zoom effect/Public
class Pulseanimator extends Baseviewanimator {
 @Override public
 Void Prepare (View target) {
 getanimatoragent (). Playtogether (
  objectanimator.offloat (target, "ScaleY", 1, 1.2f, 1),
  objectanimator.offloat (target, "ScaleX", 1, 1.2f, 1)
 );
 }

The above two kinds of animation effect is to baseviewanimator two implementations, the animation itself uses the library is nineoldandroids.

3). Finally encapsulates an animation management tool class Animhelper for external use

First defines a static class, uses helper to instantiate this static class, and sets individual parameter options.

 public class Animhelper {private static final long DURATION = baseviewanimator.duration;

 Private static final Long No_delay = 0; /** * Instantiate Animationcomposer unique interface/public static animationcomposer with (Baseviewanimator animator) {return new Anima
 Tioncomposer (animator); /** * Defines the various parameters associated with the animation effect, * Use this method to ensure that the object is constructed and his representations are isolated from each other * * public static final class Animationcomposer {private list& Lt

 animator.animatorlistener> callbacks = new arraylist<animator.animatorlistener> ();
 Private Baseviewanimator animator;
 Private long Duration = duration;
 Private long delay = No_delay;
 Private Interpolator interpolator;

 Private View target;
 Private Animationcomposer (Baseviewanimator animator) {this.animator = animator;
  Public animationcomposer duration (long duration) {this.duration = duration;
 return this;
  Public Animationcomposer delay (long delay) {this.delay = delay;
 return this; } public Animationcomposer interpolate (interpolator interpolator) {this.interpolator = Interpolator;
 return this;
  Public Animationcomposer Withlistener (Animator.animatorlistener listener) {Callbacks.add (listener);
 return this;
  Public Animmanager Playon (View target) {this.target = target;
 Return to New Animmanager (play (), this.target);
  Private Baseviewanimator Play () {animator.settarget (target);

  Animator.setduration (Duration). Setinterpolator (Interpolator). Setstartdelay (delay); if (callbacks.size () > 0) {for (Animator.animatorlistener callback:callbacks) {Animator.addanimatorlistener (ca
  Llback);
  } animator.animate ();
 return animator;
 }/** * Animation Management class * * public static final class animmanager{private baseviewanimator animator;

 Private View target;
  Private Animmanager (Baseviewanimator animator, View target) {this.target = target;
 This.animator = animator;
 public Boolean isstarted () {return animator.isstarted (); public boolean isrunning () {return animator.isrunNing ();

  public void Stop (Boolean reset) {Animator.cancel ();
 if (reset) animator.reset (target);
 }
 }

}

This code uses a similar dialog Builder mode and is interested in searching the Java design pattern-builder. Later, we'll open another tutorial.
(Note: The content of this part of the complex animation is just taken out here to show and use, the packaging and implementation is greatly original by the code home, there are want to learn more animation and effect of Please point its name link)

Run, you can see the effect shown earlier. Click on the first,, along with the icon to become larger and float out of the "+1" effect, the picture switch to the selected state, and then click Restore unchecked, and will not trigger the animation.

At this point, praise this piece of content and the focus is finished, I hope you can have a little harvest, in addition to facilitate their own also can deepen understanding.
Finally, attach the sample source address:

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.