Android开发之使用TabLayout快速实现选项卡切换功能(附源码下载)
生活随笔
收集整理的這篇文章主要介紹了
Android开发之使用TabLayout快速实现选项卡切换功能(附源码下载)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
看下效果圖:
?
先看下布局:
TabLayout的簡單使用: 當選項卡過少時候設置填充全屏app:tabGravity="fill"設置下面切換選項卡的小滑片顏色app:tabIndicatorColor="#8B1C21"設置下面切換選項卡的小滑片高度app:tabIndicatorHeight="1dp"app:tabMaxWidth="0dp"app:tabSelectedTextColor="#8B1C21" <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@null"android:orientation="vertical"><android.support.design.widget.TabLayoutandroid:id="@+id/tb_monetary"android:layout_width="match_parent"android:layout_height="40dp"android:background="#ffffff"app:tabGravity="fill"app:tabIndicatorColor="#8B1C21"app:tabIndicatorHeight="1dp"app:tabMaxWidth="0dp"app:tabSelectedTextColor="#8B1C21"/><FrameLayoutandroid:id="@+id/fl_monetary_replace"android:layout_width="match_parent"android:layout_height="match_parent"/></LinearLayout>再看下首頁activity代碼:
package kotlin.yhsh.cn.tablayoutandline;import android.os.Bundle; import android.support.annotation.Nullable; import android.support.design.widget.TabLayout; import android.support.v4.app.FragmentTransaction; import android.support.v7.app.AppCompatActivity;/*** @author DELL*/ public class MainActivity extends AppCompatActivity {private TabLayout tbMonetary;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();}private void initView() {tbMonetary = findViewById(R.id.tb_monetary);tbMonetary.addTab(tbMonetary.newTab().setText("近七日年化"));tbMonetary.addTab(tbMonetary.newTab().setText("萬份收益"));//默認七日收益getSupportFragmentManager().beginTransaction().replace(R.id.fl_monetary_replace, SevenDayMoneyFragment.newInstance()).commit();initListener();}private void initListener() {tbMonetary.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {@Overridepublic void onTabSelected(TabLayout.Tab tab) {FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();if (tab.getPosition() == 0) {//七日年化transaction.replace(R.id.fl_monetary_replace, SevenDayMoneyFragment.newInstance()).commit();} else if (tab.getPosition() == 1) {//萬份收益transaction.replace(R.id.fl_monetary_replace, OneYearMoneyFragment.newInstance()).commit();}}@Overridepublic void onTabUnselected(TabLayout.Tab tab) {}@Overridepublic void onTabReselected(TabLayout.Tab tab) {}});} }?
然后看下兩個切換的fragment代碼:
package kotlin.yhsh.cn.tablayoutandline;import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.RadioButton;import java.util.ArrayList; import java.util.List; import java.util.Random;/*** @author 下一頁5(輕飛揚)* 創建時間:2019/6/12 17:37* 個人小站:http://yhsh.wap.ai(已掛)* 最新小站:http://www.iyhsh.icoc.in* 空間名稱:group-wallet-android*/ public class SevenDayMoneyFragment extends Fragment {private View sevenDayView;//x軸數據集合List<String> xValues;//y軸數據集合List<Integer> yValues;@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {sevenDayView = View.inflate(getContext(), R.layout.fragment_seven_day_money, null);initViewID();return sevenDayView;}private void initViewID() {RadioButton rbMoneySevenDay = sevenDayView.findViewById(R.id.rb_money_seven_day);//默認選中7天rbMoneySevenDay.setChecked(true);MyLineChartView mlvFinancingLine = sevenDayView.findViewById(R.id.mlv_financing_line);xValues = new ArrayList<>();yValues = new ArrayList<>();for (int i = 1; i <= 7; i++) {Random random = new Random();xValues.add(i + "號");yValues.add(random.nextInt(1000));}// xy軸集合自己添加數據mlvFinancingLine.setXValues(xValues);mlvFinancingLine.setYValues(yValues);}public static Fragment newInstance() {return new SevenDayMoneyFragment();} }我們看下第一個fragment里面的自定義折線圖
package kotlin.yhsh.cn.tablayoutandline;import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.DashPathEffect; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View;import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List;/*** @author 下一頁5(輕飛揚)* 創建時間:2019/7/12 10:20* 個人小站:http://yhsh.wap.ai(已掛)* 空間名稱:group-wallet-android*/ public class MyLineChartView extends View {//原點x坐標private int originX;//原點y坐標private int originY;//第一個點x坐標private int firstPointX;//移動時第一個點的最小x值private int firstMinX;//移動時第一個點的最大x值private int firstMaxX;//坐標刻度的間隔private int intervalX = 130;//y軸刻度的間隔private int intervalY = 80;private List<String> xValues;private List<Integer> yValues;//控件寬度private int mWidth;//控件高度private int mHeight;//滑動時上一次手指的x坐標值private int startX;//xy軸文字大小private int xyTextSize = 24;//默認上下左右的paddingprivate int paddingTop = 140;private int paddingLeft = 160;private int paddingRight = 100;private int paddingDown = 150;//x軸刻度線高度private int scaleHeight = 10;//xy軸的文字距xy線的距離private int textToXYAxisGap = 20;//x軸左右向外延伸的長度private int leftRightExtra = intervalX / 3;// Y軸刻度個數private int lableCountY = 6;private int bigCircleR = 7;private int smallCircleR = 5;//y軸最小值private float minValueY;// y軸最大值private float maxValueY = 0;//比例圖線段長度private int shortLine = 34;private Paint paintWhite, paintBlue, paintRed, paintBack, paintText;//view的背景顏色private int backGroundColor = Color.parseColor("#ffffff");private GestureDetector gestureDetector;private String legendTitle = "漲停";public MyLineChartView(Context context) {this(context, null);}public MyLineChartView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public MyLineChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initPaint();gestureDetector = new GestureDetector(context, new MyOnGestureListener());}private void initPaint() {paintWhite = new Paint(Paint.ANTI_ALIAS_FLAG);paintWhite.setColor(Color.parseColor("#5C6170"));paintWhite.setStyle(Paint.Style.STROKE);paintBlue = new Paint(Paint.ANTI_ALIAS_FLAG);paintBlue.setColor(Color.parseColor("#5C6170"));paintBlue.setStrokeWidth(3f);paintBlue.setStyle(Paint.Style.STROKE);paintBack = new Paint(Paint.ANTI_ALIAS_FLAG);paintBack.setColor(Color.parseColor("#ffffff"));paintBack.setStyle(Paint.Style.FILL);paintRed = new Paint(Paint.ANTI_ALIAS_FLAG);paintRed.setColor(Color.RED);paintRed.setStrokeWidth(3f);paintRed.setStyle(Paint.Style.STROKE);paintText = new Paint(Paint.ANTI_ALIAS_FLAG);paintText.setColor(Color.parseColor("#5C6170"));paintText.setTextSize(xyTextSize);paintText.setStrokeWidth(2f);}@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {if (changed) {mWidth = getWidth();mHeight = getHeight();originX = paddingLeft - leftRightExtra;originY = mHeight - paddingDown;firstPointX = paddingLeft;firstMinX = mWidth - originX - (xValues.size() - 1) * intervalX - leftRightExtra;// 滑動時,第一個點x值最大為paddingLeft,在大于這個值就不能滑動了firstMaxX = firstPointX;setBackgroundColor(backGroundColor);}super.onLayout(changed, left, top, right, bottom);}@Overrideprotected void onDraw(Canvas canvas) {drawX(canvas);drawBrokenLine(canvas);drawY(canvas);drawLegend(canvas);}/*** 畫x軸** @param canvas*/private void drawX(Canvas canvas) {Path path = new Path();path.moveTo(originX, originY);for (int i = 0; i < xValues.size(); i++) {// x軸線 寫死不變path.lineTo(mWidth - paddingRight, originY);// x軸箭頭canvas.drawLine(mWidth - paddingRight, originY, mWidth - paddingRight - 15, originY + 10, paintWhite);canvas.drawLine(mWidth - paddingRight, originY, mWidth - paddingRight - 15, originY - 10, paintWhite);// x軸線上的刻度線canvas.drawLine(firstPointX + i * intervalX, originY, firstPointX + i * intervalX, originY - scaleHeight, paintWhite);// x軸上的文字canvas.drawText(xValues.get(i), firstPointX + i * intervalX - getTextWidth(paintText, "17.01") / 2,originY + textToXYAxisGap + getTextHeight(paintText, "17.01"), paintText);}canvas.drawPath(path, paintWhite);// x軸虛線Paint p = new Paint();p.setStyle(Paint.Style.STROKE);p.setColor(Color.parseColor("#5C6170"));Path path1 = new Path();DashPathEffect dash = new DashPathEffect(new float[]{8, 10, 8, 10}, 0);p.setPathEffect(dash);for (int i = 0; i < lableCountY; i++) {path1.moveTo(originX, mHeight - paddingDown - leftRightExtra - i * intervalY);path1.lineTo(mWidth - paddingRight, mHeight - paddingDown - leftRightExtra - i * intervalY);}canvas.drawPath(path1, p);}/*** 畫折線** @param canvas*/private void drawBrokenLine(Canvas canvas) {canvas.save();// y軸文字minValueY = yValues.get(0);for (int i = 0; i < yValues.size(); i++) {// 找出y軸的最大最小值if (yValues.get(i) > maxValueY) {maxValueY = yValues.get(i);}if (yValues.get(i) < minValueY) {minValueY = yValues.get(i);}}// 畫折線float aver = (lableCountY - 1) * intervalY / (maxValueY - minValueY);Path path = new Path();for (int i = 0; i < yValues.size(); i++) {if (i == 0) {path.moveTo(firstPointX, mHeight - paddingDown - leftRightExtra - yValues.get(i) * aver + minValueY * aver);} else {path.lineTo(firstPointX + i * intervalX, mHeight - paddingDown - leftRightExtra - yValues.get(i) * aver + minValueY * aver);}}canvas.drawPath(path, paintBlue);// 折線中的圓點for (int i = 0; i < yValues.size(); i++) {canvas.drawCircle(firstPointX + i * intervalX,mHeight - paddingDown - leftRightExtra - yValues.get(i) * aver + minValueY * aver, bigCircleR, paintBlue);canvas.drawCircle(firstPointX + i * intervalX,mHeight - paddingDown - leftRightExtra - yValues.get(i) * aver + minValueY * aver, smallCircleR, paintBack);}//將折線超出x軸坐標的部分截取掉(左邊)paintBack.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));RectF rectF = new RectF(0, 0, originX, mHeight);canvas.drawRect(rectF, paintBack);canvas.restore();}/*** 畫y軸** @param canvas*/private void drawY(Canvas canvas) {canvas.save();Path path = new Path();path.moveTo(originX, originY);for (int i = 0; i < lableCountY; i++) {// y軸線if (i == 0) {path.lineTo(originX, mHeight - paddingDown - leftRightExtra);} else {path.lineTo(originX, mHeight - paddingDown - leftRightExtra - i * intervalY);}int lastPointY = mHeight - paddingDown - leftRightExtra - i * intervalY;if (i == lableCountY - 1) {int lastY = lastPointY - leftRightExtra - leftRightExtra / 2;// y軸最后一個點后,需要額外加上一小段,就是一個半leftRightExtra的長度canvas.drawLine(originX, lastPointY, originX, lastY, paintWhite);// y軸箭頭canvas.drawLine(originX, lastY, originX - 10, lastY + 15, paintWhite);canvas.drawLine(originX, lastY, originX + 10, lastY + 15, paintWhite);}}canvas.drawPath(path, paintWhite);// y軸文字float space = (maxValueY - minValueY) / (lableCountY - 1);DecimalFormat decimalFormat = new DecimalFormat("0.00");List<String> yTitles = new ArrayList<>();for (int i = 0; i < lableCountY; i++) {yTitles.add(decimalFormat.format(minValueY + i * space));}for (int i = 0; i < yTitles.size(); i++) {canvas.drawText(yTitles.get(i), originX - textToXYAxisGap - getTextWidth(paintText, "00.00"),mHeight - paddingDown - leftRightExtra - i * intervalY + getTextHeight(paintText, "00.00") / 2, paintText);}// 截取折線超出部分(右邊)paintBack.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));RectF rectF = new RectF(mWidth - paddingRight, 0, mWidth, mHeight);canvas.drawRect(rectF, paintBack);canvas.restore();}/*** 畫圖例*/private void drawLegend(Canvas canvas) {// 開始點的坐標int x = 350;int y = mHeight - (paddingDown - textToXYAxisGap - getTextHeight(paintText, "06.00")) / 2;canvas.save();canvas.drawLine(x, y, x + 2 * shortLine, y, paintBlue);canvas.drawCircle(x + shortLine, y, bigCircleR, paintBlue);canvas.drawCircle(x + shortLine, y, smallCircleR, paintBack);canvas.drawText(legendTitle, x + 2 * shortLine + 10, y + getTextHeight(paintText, legendTitle) / 2 - 2, paintText);canvas.drawLine(x + 2 * shortLine + getTextWidth(paintText, legendTitle) + 20,y, x + 2 * shortLine + getTextWidth(paintText, legendTitle) + 20 + 2 * shortLine, y, paintRed);canvas.drawCircle(x + 2 * shortLine + getTextWidth(paintText, legendTitle) + 20 + shortLine, y, bigCircleR, paintRed);canvas.drawCircle(x + 2 * shortLine + getTextWidth(paintText, legendTitle) + 20 + shortLine, y, smallCircleR, paintBack);canvas.drawText("漲停", x + 2 * shortLine + getTextWidth(paintText, legendTitle) + 30 + 2 * shortLine,y + getTextHeight(paintText, legendTitle) / 2 - 2, paintText);canvas.restore();}/*** 手勢事件*/class MyOnGestureListener implements GestureDetector.OnGestureListener {@Overridepublic boolean onDown(MotionEvent e) { // 按下事件return false;}// 按下停留時間超過瞬時,并且按下時沒有松開或拖動,就會執行此方法@Overridepublic void onShowPress(MotionEvent motionEvent) {}@Overridepublic boolean onSingleTapUp(MotionEvent motionEvent) { // 單擊抬起return false;}@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {if (e1.getX() > originX && e1.getX() < mWidth - paddingRight &&e1.getY() > paddingTop && e1.getY() < mHeight - paddingDown) {//注意:這里的distanceX是e1.getX()-e2.getX()distanceX = -distanceX;if (firstPointX + distanceX > firstMaxX) {firstPointX = firstMaxX;} else if (firstPointX + distanceX < firstMinX) {firstPointX = firstMinX;} else {firstPointX = (int) (firstPointX + distanceX);}invalidate();}return false;}@Overridepublic void onLongPress(MotionEvent motionEvent) {} // 長按事件@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {return false;}}@Overridepublic boolean onTouchEvent(MotionEvent event) {if (yValues.size() < 7) {return false;}gestureDetector.onTouchEvent(event);return true;}public void setXValues(List<String> values) {this.xValues = values;}public void setYValues(List<Integer> values) {this.yValues = values;}/*** 獲取文字的寬度** @param paint* @param text* @return*/private int getTextWidth(Paint paint, String text) {return (int) paint.measureText(text);}/*** 獲取文字的高度** @param paint* @param text* @return*/private int getTextHeight(Paint paint, String text) {Rect rect = new Rect();paint.getTextBounds(text, 0, text.length(), rect);return rect.height();} }?
第二個fragment是空的
package com.yhsh.financing.home;import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup;import com.yhsh.financing.R; import com.yhsh.mobile.common.base.BaseFragment;/*** @author 下一頁5(輕飛揚)* 創建時間:2019/6/12 17:37* 個人小站:http://yhsh.wap.ai(已掛)* 最新小站:http://www.iyhsh.icoc.in* 空間名稱:group-wallet-android* 項目包名:com.yhsh.financing.home*/ public class OneYearMoneyFragment extends BaseFragment {private View oneYearView;@Overridepublic View generateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {oneYearView = View.inflate(mContext, R.layout.fragment_one_year_money, null);return oneYearView;}public static Fragment newInstance() {return new OneYearMoneyFragment();} }可下載源碼:CSDN下載? ??GitHub下載
代碼中自定義的折線圖源碼感謝博主:自定義折線圖博主
總結
以上是生活随笔為你收集整理的Android开发之使用TabLayout快速实现选项卡切换功能(附源码下载)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 声音播放
- 下一篇: 怎样安装 Svelte