In this
article I want to share one of the ways to develop a nice animated menu or text
horizontal list.
Concept
To
implement such a list, I'm using a TextSwitcher. This element contains a
TextView, which we may customize on your own.
TextSwitcher
useful for changing animated text. We will use 3 TextSwitcher. Main Switcher
used to identify the current list element, and the side - for navigation
options and display elements of the next.
For the
shadowing effect, we will create a gradient TextView with the transition from
transparent to the desired color.
Preparing resources
To start
the animation will develop change the text from left to right and right to left.
Source code
anim/push_left_in.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"
>
<translate
android:duration="300"
android:fromXDelta="-100%p"
android:toXDelta="0" />
<alpha
android:duration="300"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
</set>
Source code
anim/push_left_out.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"
>
<translate
android:duration="300"
android:fromXDelta="0"
android:toXDelta="-100%p" />
<alpha
android:duration="300"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
</set>
Source code
anim/push_right_in.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"
>
<translate
android:duration="300"
android:fromXDelta="100%p"
android:toXDelta="0" />
<alpha
android:duration="300"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
</set>
Source code
anim/push_right_out.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"
>
<translate
android:duration="300"
android:fromXDelta="0"
android:toXDelta="100%p" />
<alpha
android:duration="300"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
</set>
For
Gradient TextView to describe its properties:
Source code
values/attrs.xml
<resources>
<declare-styleable name="GradientTextView">
<attr name="colorStartGradient"
format="integer" />
<attr name="colorEndGradient"
format="integer" />
</declare-styleable>
</resources>
As well add
color for the gradient:
Source code
values/colors.xml
<resources>
<color name="textview_start_gradient">#00ffffff</color>
<color name="textview_end_gradient">#88ffffff</color>
</resources>
Develop the
the main layout of the window, which will contain our animated menu:
Source code
layout/main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextSwitcher
android:id="@+id/scoreboard_location_left"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<TextSwitcher
android:id="@+id/scoreboard_location"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<TextSwitcher
android:id="@+id/scoreboard_location_right"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
TextSwitcher
contains a TextView. Our project will use two types of text controls: normal
(for the central element) and the gradient (for side elements).
Source code
layout/central_textview.xml
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:id="@+id/textview"
/>
Source code
layout/gradient_textview.xml
<org.snowpard.proects.twenty.GradientTextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/org.snowpard.proects.twenty"
android:id="@+id/textview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
app:colorEndGradient="@color/textview_end_gradient"
app:colorStartGradient="@color/textview_start_gradient"
/>
Developing
- Create Gradient TextView
public class GradientTextView extends TextView { private int colorStartGradient, colorEndGradient; private boolean direction; private LinearGradient gradient; public GradientTextView(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.GradientTextView); colorStartGradient = a.getColor(R.styleable.GradientTextView_colorStartGradient, -2); colorEndGradient = a.getColor(R.styleable.GradientTextView_colorEndGradient, -2); direction = false; } public void setDirection(boolean direction) { this.direction = direction; } @Override protected void onDraw(Canvas canvas) { if (colorStartGradient != -2 && colorEndGradient != -2) { gradient = new LinearGradient(direction ? getWidth() : 0, 0, direction ? 0 : getWidth(), 0, colorStartGradient, colorEndGradient, TileMode.CLAMP); getPaint().setShader(gradient); } super.onDraw(canvas); } }
- Development of the main class MainActivity, work with a horizontal menu.
Add a
constant in the class, which will be responsible for the direction of the
animation.
public static final int DIRECTION_NONE = 0; public static final int DIRECTION_LEFT = 1; public static final int DIRECTION_RIGHT = 2; private int current_direction = DIRECTION_RIGHT;
We describe the controls and animations that will be used to operate the menu:
private TextSwitcher switcher, switcher_left, switcher_right; private Animation in_left, in_right, out_left, out_right;
And to add an array of items for the horizontal menu and the index for the identification of the current element:
private String[] locations = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"}; private int current_index;
Develop a method of for working with a horizontal menu:
-
setAnimation: to set the desired animation to change the text
private void setAnimation(TextSwitcher switcher, Animation in, Animation out) { switcher.setInAnimation(in); switcher.setOutAnimation(out); }
-
initSwitch: initialization TextSwitcher
private void initSwitch(TextSwitcher switcher, final int place, Animation in, Animation out, final Context context) { switcher.setFactory(new ViewFactory() { @Override public View makeView() { TextView view = (TextView)LayoutInflater.from(context).inflate((place == 0) ? R.layout.central_textview: R.layout.gradient_textview, null).findViewById(R.id.textview); if (view instanceof GradientTextView) ((GradientTextView)view).setDirection(place != 1); return view; } }); setAnimation(switcher, in, out); }
-
setSwitch: change an item in the horizontal menu
private void setSwitch(int direction) { boolean isUpdate = false; if (direction == DIRECTION_LEFT && current_index > 0) { isUpdate = true; current_index--; } else if (direction == DIRECTION_RIGHT && current_index < locations.length - 1) { isUpdate = true; current_index++; } else if (direction == DIRECTION_NONE) isUpdate = true; if (isUpdate) { if (direction != current_direction && direction != DIRECTION_NONE) { current_direction = direction; if (current_direction == DIRECTION_RIGHT) { setAnimation(switcher_left, in_right, out_left); setAnimation(switcher, in_right, out_left); setAnimation(switcher_right, in_right, out_left); } else { setAnimation(switcher_left, in_left, out_right); setAnimation(switcher, in_left, out_right); setAnimation(switcher_right, in_left, out_right); } } if (current_index - 1 >= 0) switcher_left.setText(locations[current_index - 1]); else switcher_left.setText(""); switcher.setText(locations[current_index]); if (current_index + 1 <= locations.length - 1) switcher_right.setText(locations[current_index + 1]); else switcher_right.setText(""); } }
Now you
need to initialize all in the method onCreate() of our Activity:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); in_left = AnimationUtils.loadAnimation(this, R.anim.push_left_in); in_right = AnimationUtils.loadAnimation(this, R.anim.push_right_in); out_right = AnimationUtils.loadAnimation(this, R.anim.push_right_out); out_left = AnimationUtils.loadAnimation(this, R.anim.push_left_out); switcher = (TextSwitcher) findViewById(R.id.scoreboard_location); switcher_left = (TextSwitcher) findViewById(R.id.scoreboard_location_left); switcher_right = (TextSwitcher) findViewById(R.id.scoreboard_location_right); initSwitch(switcher, 0, in_right, out_left, this); initSwitch(switcher_left, 1, in_right, out_left, this); initSwitch(switcher_right, 2, in_right, out_left, this); switcher_left.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { setSwitch(DIRECTION_LEFT); } }); switcher_right.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { setSwitch(DIRECTION_RIGHT); } }); setSwitch(DIRECTION_NONE); }
Links
- The source codes of this project can be downloaded here: zip
No comments:
Post a Comment