# # # 1. The overview
Recently, I have been imitating the effects of other projects, such as connotation jokes, used car Home, etc. Will one day be caught is really a little guilty, I am clearly advertising for these apps. When these effects are basically finished, we will start to design the mode and system framework of a set of videos will come out, and when the total number of visits reaches 1 million, we will use our spare time to record the Java foundation and Android foundation, please start and suggest a lot. Let’s take a look at the effect:
# # # 2. Effect of implementation
2.1 Integration of the previous example:
Bottom Fragment switch and list plus round broadcast bar are from the last blog Android Fragment from the source point of view to parse (below) directly taken from the effect, we here mainly realize the home page ViewPager indicator color effect and switch effect. In fact, I have long wanted to write this effect, may be the brain short circuit at that time did not go to too much to think, and then I thought of the way to achieve it did not go to write afraid of circumlocution on the Internet comparison just began, so we will be completely to achieve it. 2.2 Implementation Ideas:
And when we see that, we’re like, what the hell? 2.2.1 We must customize the View, but from whom? If you look at the onMesure() method of a TextView, you’ll see that it’s much less code than if you inherited it from a View. 2.2.2 How to achieve discoloration? Definitely need to draw, as long as two brushes constantly draw their respective regions can be out. 2.2.3 No, but we need to move to know. Let’s implement a TextView with two colors first.
Let’s first implement a simple effect: a TextView with two colors, black and red? The general idea is: 2.3.2 In onDraw() we use the calculated split position to draw the text ourselves. DrawText (String text, float x, float y, Paint Paint) : canvas. DrawText (String text, float x, float y, Paint Paint) Y is the baseline of the text. Here is a picture:
/** * Created by Darren on 2016/12/5. * Email: [email protected] * Description: Public class ColorTrackTextView extends TextView {public class ColorTrackTextView extends TextView {private Paint mOriginPaint; // Change the font color of the brush private Paint mChangePaint; // Current progress privatefloatMCurrentProgress = 0.6 f; private String TAG ="CTTV"; // Current text private String mText; public ColorTrackTextView(Context context) { this(context, null); } public ColorTrackTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ColorTrackTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initPaint(); } /** * initializes the brush */ private voidinitPaint() { mOriginPaint = getPaintByColor(Color.BLACK); mChangePaint = getPaintByColor(Color.RED); Private Paint getPaintByColor(int color) {Paint Paint = new Paint(); // Antialiasing paint.setantialias (true); // Copy dither paint. SetDither (true); paint.setColor(color); // Set the font size to the TextView text size paint.settextSize (getTextSize());returnpaint; } @override protected void onDraw(Canvas Canvas) {// get the current text mText = getText().tostring (); Int width = getWidth();if(! Int middle = (int) (width * mCurrentProgress); textutils.isEmpty (mText)) {int middle = (int) (width * mCurrentProgress); drawOrigin(canvas, middle); drawChange(canvas, middle); Private void drawChange(Canvas, int middle) {drawText(Canvas, mChangePaint, 0, middle); } /** * private void drawOrigin(Canvas Canvas, int middle) {drawText(Canvas, mOriginPaint, middle, getWidth()); } /** * Draws text according to the specified position ** @param canvas canvas * @param paint brush * @param startX start position * @param endX end position */ private Void drawText(Canvas Canvas, Paint Paint, int startX, int endX) {// Save Canvas. Save (); Canvas. ClipRect (startX, 0, endX, getHeight())); Rect bounds = new Rect(); mOriginPaint.getTextBounds(mText, 0, mText.length(), bounds); / / text for the Metrics used to calculate the baseline Paint. FontMetricsInt fontMetrics = mOriginPaint. GetFontMetricsInt (); Int fontTotalHeight = fontMetrics. Bottom-fontmetrics. Top; Int offY = fontTotalHeight / 2 - fontMetrics. Int measuredHeight = (measuredheight () + measuretTotalheight) / 2 - measuremeasurey; canvas.drawText(mText, getMeasuredWidth() / 2 - bounds.width() / 2, baseline, paint); // Release the paintbrush state canvas.restore(); }}Copy the code
Look at the above code is actually quite simple, I cut a rendering
2.4 Achieve continuous color change in different directions: So once we have a TextView with two text colors, what we’re going to do is we’re going to constantly control the current progress of the mCurrentProgress variable and then we’re going to draw the two orientations from left to right, right to left, and we’re going to change the two color values that are dead to custom properties. If you have to wait until the weekend to watch the video, I’m not going to do too much here. I only post the modified part of the code here, if you feel a bit silly then download the full code:
Private Direction mDirection = DIRECTION_LEFT; Public enum Direction {DIRECTION_LEFT, } @override protected void onDraw(Canvas Canvas) {mText = getText().tostring (); Int width = getWidth();if(! Int middle = (int) (width * mCurrentProgress); textutils.isEmpty (mText)) {int middle = (int) (width * mCurrentProgress); // Draw the font according to the different orientationif (mDirection == DIRECTION_LEFT) {
drawOriginDirectionLeft(canvas, middle);
drawChangeDirectionLeft(canvas, middle);
}
if(mDirection == DIRECTION_RIGHT) { drawOriginDirectionRight(canvas, middle); drawChangeDirectionRight(canvas, middle); Private void drawChangeDirectionRight(Canvas Canvas, int middle) {drawText(Canvas, int middle); mChangePaint, getWidth() - middle, getWidth()); } /** * private void drawOriginDirectionRight(Canvas, int middle) {drawText(Canvas, mOriginPaint, drawText(Canvas, mOriginPaint, drawText) 0, getWidth() - middle); } /** * private void drawChangeDirectionLeft(Canvas, int middle) {drawText(Canvas, mChangePaint, 0, middle); } /** * private void drawOriginDirectionLeft(Canvas, int middle) {drawText(Canvas, mOriginPaint, drawText(Canvas, mOriginPaint, drawText(Canvas, mOriginPaint, drawText); middle, getWidth()); } @param currentProgress currentProgress */ public voidsetCurrentProgress(floatcurrentProgress) { this.mCurrentProgress = currentProgress; // redraw invalidate(); } /** * sets the drawing direction, from right to left or from left to right ** @param direction Specifies the drawing direction */ public voidsetDirection(Direction direction) {
this.mDirection = direction;
}
Copy the code
Let’s test this by writing a main Activity:
public class MainActivity extends AppCompatActivity {
private ColorTrackTextView mCttv;
private String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); mCttv = (ColorTrackTextView) findViewById(R.id.tv); } // the onClick event is not centered --> Android :onClick="left"Public void left View (View) {/ / set towards mCttv setDirection (ColorTrackTextView. Direction. DIRECTION_LEFT); ObjectAnimator animator = objectAnimator.offloat (mCttv,"progress", 0, 1); animator.setDuration(2000) .start(); / / add animation listening, changing the current progress animator. AddUpdateListener (new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float progress = (float) animation.getAnimatedValue();
Log.e(TAG, "progress --> "+ progress); mCttv.setCurrentProgress(progress); }}); } / / it is similar to the above, just toward different public void right View (View) {mCttv. SetDirection (ColorTrackTextView. Direction. DIRECTION_RIGHT); ObjectAnimator animator = ObjectAnimator.ofFloat(mCttv,"progress", 0, 1);
animator.setDuration(2000)
.start();
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float progress = (float) animation.getAnimatedValue();
Log.e(TAG, "progress --> "+ progress); mCttv.setCurrentProgress(progress); }}); }}Copy the code
End result:
2.5 With ViewPager:
public class MainActivity extends AppCompatActivity {
private String[] items = {"Live"."Recommended"."Video"."Image"."Jokes"."Essence"};
private LinearLayout mIndicatorContainer;
private List<ColorTrackTextView> mIndicators;
private ViewPager mViewPager;
private String TAG = "ViewPagerActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_pager); mIndicators = new ArrayList<>(); mIndicatorContainer = (LinearLayout) findViewById(R.id.indicator_view); mViewPager = (ViewPager) findViewById(R.id.view_pager); initIndicator(); initViewPager(); } /** * initialize ViewPager */ private voidinitViewPager() { mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) { @Override public Fragment getItem(int position) {return ItemFragment.newInstance(items[position]);
}
@Override
public int getCount() {
returnitems.length; } @Override public void destroyItem(ViewGroup container, int position, Object object) { } }); /** * add a switch to listen on thatsetOnPageChangeListener obsolete the go to see the source code * * / mViewPager addOnPageChangeListener (new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
Log.e(TAG, "position --> " + position + " positionOffset --> " + positionOffset);
if(positionOffset > 0) {// Get the left ColorTrackTextView left = mindicators.get (position); / / set toward the left. SetDirection (ColorTrackTextView. Direction. DIRECTION_RIGHT); SetCurrentProgress (1-positionOffset); // Set the positionOffset from 0 to 1. // Get ColorTrackTextView right = mindicators. get(position + 1); right.setDirection(ColorTrackTextView.Direction.DIRECTION_LEFT); right.setCurrentProgress(positionOffset); }}}); ColorTrackTextView left = mindicators.get (0); left.setDirection(ColorTrackTextView.Direction.DIRECTION_RIGHT); left.setCurrentProgress(1); } /** * initializes the color-changing indicator */ private voidinitIndicator() {
for(int i = 0; i < items.length; Adding color i++) {/ / dynamic tracking TextView LinearLayout. LayoutParams params = new LinearLayout. LayoutParams ( ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT); params.weight = 1; ColorTrackTextView colorTrackTextView = new ColorTrackTextView(this); / / set the two colors colorTrackTextView. SetOriginColor (Color. BLACK); colorTrackTextView.setChangeColor(Color.RED); colorTrackTextView.setText(items[i]); colorTrackTextView.setLayoutParams(params); / / add new LinearLayout container mIndicatorContainer. AddView (colorTrackTextView); // Add the collection mindicators. add(colorTrackTextView); }}}Copy the code
So far it should be pretty simple, just change the color, there is a tricky problem is the current indicator is using a LinearLayout. We can go to the Internet to find a ViewPagerIndicator source code to test, but I think it is not particularly useful configuration is very troublesome, so WE decided to use Adapter Adapter mode to build a wheel. In fact, his early wrote a, download people still quite many, but the code has a problem, so or record a video, there is a problem we can change their own.
Attached to the video address: http://pan.baidu.com/s/1jI9PgUE