!14624 [MS][Lite]remove some copy codes

From: @sishuikang
Reviewed-by: @zhanghaibo5,@zhanghaibo5,@hangangqiang
Signed-off-by: @zhanghaibo5
This commit is contained in:
mindspore-ci-bot 2021-04-06 16:48:26 +08:00 committed by Gitee
commit f328ecd300
46 changed files with 396 additions and 3677 deletions

View File

@ -15,9 +15,10 @@
*/
package com.mindspore.himindspore.bean;
import com.mindspore.customview.tablayout.listener.CustomTabEntity;
public class TabEntity implements CustomTabEntity {
import com.mindspore.himindspore.ui.view.MSTabEntity;
public class TabEntity implements MSTabEntity {
public String title;
public int selectedIcon;
@ -30,17 +31,17 @@ public class TabEntity implements CustomTabEntity {
}
@Override
public String getTabTitle() {
public String getMSTabTitle() {
return title;
}
@Override
public int getTabSelectedIcon() {
public int getMSTabIconChecked() {
return selectedIcon;
}
@Override
public int getTabUnselectedIcon() {
public int getMSTabIconUnchecked() {
return unSelectedIcon;
}
}

View File

@ -40,7 +40,7 @@ import androidx.appcompat.app.AlertDialog;
import com.mindspore.common.sp.Preferences;
import com.mindspore.common.utils.Utils;
import com.mindspore.customview.countdown.CountDownView;
import com.mindspore.customview.countdown.MSCountDownView;
import com.mindspore.himindspore.R;
import com.mindspore.himindspore.base.BaseActivity;
import com.mindspore.himindspore.ui.main.MainActivity;
@ -63,7 +63,7 @@ public class SplashActivity extends BaseActivity implements EasyPermissions.Perm
private SharedPreferences prefs;
private CountDownView cdvTime;
private MSCountDownView cdvTime;
private boolean isCheckPrivacy = false;
private View mContentView;

View File

@ -24,22 +24,25 @@ import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.core.content.FileProvider;
import androidx.fragment.app.Fragment;
import androidx.viewpager.widget.ViewPager;
import com.google.android.material.tabs.TabLayout;
import com.mindspore.common.base.adapter.BasePagerAdapter;
import com.mindspore.customview.dialog.UpdateDialog;
import com.mindspore.customview.tablayout.CommonTabLayout;
import com.mindspore.customview.tablayout.listener.CustomTabEntity;
import com.mindspore.customview.tablayout.listener.OnTabSelectListener;
import com.mindspore.himindspore.R;
import com.mindspore.himindspore.base.BaseActivity;
import com.mindspore.himindspore.comment.FragmentFactory;
import com.mindspore.himindspore.net.FileDownLoadObserver;
import com.mindspore.himindspore.net.UpdateInfoBean;
import com.mindspore.himindspore.ui.view.MSTabEntity;
import java.io.File;
import java.util.ArrayList;
@ -49,16 +52,18 @@ public class MainActivity extends BaseActivity<MainPresenter> implements MainCon
private static final String TAG = "MainActivity";
private ViewPager mVpHome;
private CommonTabLayout mCtlTable;
private TabLayout mTabLayout;
private int now_version;
private ProgressDialog progressDialog;
private List<MSTabEntity> mTabEntities;
@Override
protected void init() {
presenter = new MainPresenter(this);
mVpHome = findViewById(R.id.vp_home);
mCtlTable = findViewById(R.id.ctl_table);
mTabLayout = findViewById(R.id.tab_layout);
showPackaeInfo();
initTabLayout();
initViewPager();
@ -82,19 +87,68 @@ public class MainActivity extends BaseActivity<MainPresenter> implements MainCon
}
private void initTabLayout() {
ArrayList<CustomTabEntity> mTabEntities = presenter.getTabEntity();
mCtlTable.setTabData(mTabEntities);
mCtlTable.setOnTabSelectListener(new OnTabSelectListener() {
mTabEntities = presenter.getTabEntity();
for (int i = 0; i < mTabEntities.size(); i++) {
mTabLayout.addTab(mTabLayout.newTab().setCustomView(getTabView(mTabEntities.get(i))));
}
chooseFirst();
mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelect(int position) {
mVpHome.setCurrentItem(position);
public void onTabSelected(TabLayout.Tab tab) {
Log.e(TAG, "onTabSelected: " + tab.getPosition());
mVpHome.setCurrentItem(tab.getPosition(),true);
recoverItem();
View view =tab.getCustomView();
ImageView imageView = view.findViewById(R.id.tab_icon);
TextView textView = view.findViewById(R.id.tab_title);
imageView.setImageResource(mTabEntities.get(tab.getPosition()).getMSTabIconChecked());
textView.setTextColor(getResources().getColor(R.color.main_tab_text_checked));
}
@Override
public void onTabReselect(int position) {
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
public View getTabView(MSTabEntity tabEntity) {
View view = LayoutInflater.from(this).inflate(R.layout.layout_tab_top, null);
ImageView tabIcon = view.findViewById(R.id.tab_icon);
tabIcon.setImageResource(tabEntity.getMSTabIconUnchecked());
TextView tabText = view.findViewById(R.id.tab_title);
tabText.setText(tabEntity.getMSTabTitle());
tabText.setTextColor(getResources().getColor(R.color.main_tab_text_uncheck));
return view;
}
private void chooseFirst() {
TabLayout.Tab tabAt = mTabLayout.getTabAt(0);
View view = tabAt.getCustomView();
ImageView imageView = view.findViewById(R.id.tab_icon);
TextView textView = view.findViewById(R.id.tab_title);
imageView.setImageResource(mTabEntities.get(0).getMSTabIconChecked());
textView.setTextColor(getResources().getColor(R.color.main_tab_text_checked));
}
private void recoverItem() {
for (int i = 0; i < mTabEntities.size(); i++) {
TabLayout.Tab tabAt = mTabLayout.getTabAt(i);
View view = tabAt.getCustomView();
ImageView imageView = view.findViewById(R.id.tab_icon);
TextView textView = view.findViewById(R.id.tab_title);
imageView.setImageResource(mTabEntities.get(i).getMSTabIconUnchecked());
textView.setTextColor(getResources().getColor(R.color.main_tab_text_uncheck));
}
}
private void initViewPager() {
@ -104,23 +158,7 @@ public class MainActivity extends BaseActivity<MainPresenter> implements MainCon
fragments.add(FragmentFactory.getInstance().getMeFragment());
BasePagerAdapter adapter = new BasePagerAdapter(getSupportFragmentManager(), fragments);
mVpHome.setAdapter(adapter);
mVpHome.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if (position >= 0) {
mCtlTable.setCurrentTab(position);
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
mVpHome.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabLayout));
mVpHome.setOffscreenPageLimit(3);
mVpHome.setCurrentItem(0);
}
@ -171,7 +209,7 @@ public class MainActivity extends BaseActivity<MainPresenter> implements MainCon
public void showUpdate(final UpdateInfoBean updateInfo) {
if (now_version != updateInfo.getVersionCode()) {
UpdateDialog updateDialog= new UpdateDialog(this);
UpdateDialog updateDialog = new UpdateDialog(this);
updateDialog.setTitleString(getResources().getString(R.string.app_update_lastest) + updateInfo.getVersionName());
updateDialog.setContentString(updateInfo.getMessage());
updateDialog.setYesOnclickListener(() -> downFile());
@ -201,12 +239,9 @@ public class MainActivity extends BaseActivity<MainPresenter> implements MainCon
@Override
public void onProgress(final int progress, final long total) {
runOnUiThread(new Runnable() {
@Override
public void run() {
progressDialog.setMax((int) total / 1024 / 1024);
progressDialog.setProgress(progress);
}
runOnUiThread(() -> {
progressDialog.setMax((int) total / 1024 / 1024);
progressDialog.setProgress(progress);
});
}

View File

@ -15,12 +15,12 @@
*/
package com.mindspore.himindspore.ui.main;
import com.mindspore.customview.tablayout.listener.CustomTabEntity;
import com.mindspore.himindspore.net.FileDownLoadObserver;
import com.mindspore.himindspore.net.UpdateInfoBean;
import com.mindspore.himindspore.ui.view.MSTabEntity;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public interface MainContract {
@ -31,7 +31,7 @@ public interface MainContract {
}
interface Presenter {
ArrayList<CustomTabEntity> getTabEntity();
List<MSTabEntity> getTabEntity();
void getUpdateInfo();

View File

@ -19,13 +19,13 @@ import android.content.res.TypedArray;
import android.util.Log;
import com.mindspore.common.utils.Utils;
import com.mindspore.customview.tablayout.listener.CustomTabEntity;
import com.mindspore.himindspore.R;
import com.mindspore.himindspore.base.BasePresenter;
import com.mindspore.himindspore.bean.TabEntity;
import com.mindspore.himindspore.net.FileDownLoadObserver;
import com.mindspore.himindspore.net.RetrofitHelper;
import com.mindspore.himindspore.net.UpdateInfoBean;
import com.mindspore.himindspore.ui.view.MSTabEntity;
import java.io.File;
import java.util.ArrayList;
@ -51,15 +51,15 @@ public class MainPresenter extends BasePresenter<MainActivity> implements MainCo
@Override
public ArrayList<CustomTabEntity> getTabEntity() {
ArrayList<CustomTabEntity> mTabEntities = new ArrayList<>();
public ArrayList<MSTabEntity> getTabEntity() {
ArrayList<MSTabEntity> mTabEntities = new ArrayList<>();
TypedArray mIconUnSelectIds = Utils.getApp().getResources().obtainTypedArray(R.array.main_tab_un_select);
TypedArray mIconSelectIds = Utils.getApp().getResources().obtainTypedArray(R.array.main_tab_select);
String[] mainTitles = Utils.getApp().getResources().getStringArray(R.array.main_tab_title);
for (int i = 0; i < mainTitles.length; i++) {
int unSelectId = mIconUnSelectIds.getResourceId(i, R.drawable.experience_uncheck);
int selectId = mIconSelectIds.getResourceId(i, R.drawable.experience_checked);
mTabEntities.add(new TabEntity(mainTitles[i],selectId , unSelectId));
mTabEntities.add(new TabEntity(mainTitles[i], selectId, unSelectId));
}
mIconUnSelectIds.recycle();
mIconSelectIds.recycle();

View File

@ -13,16 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mindspore.customview.tablayout.listener;
package com.mindspore.himindspore.ui.view;
import androidx.annotation.DrawableRes;
public interface CustomTabEntity {
String getTabTitle();
public interface MSTabEntity {
String getMSTabTitle();
@DrawableRes
int getTabSelectedIcon();
int getMSTabIconChecked();
@DrawableRes
int getTabUnselectedIcon();
int getMSTabIconUnchecked();
}

View File

@ -1,43 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<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:orientation="vertical">
<com.mindspore.customview.tablayout.CommonTabLayout
android:layout_alignParentBottom="true"
android:id="@+id/ctl_table"
<androidx.viewpager.widget.ViewPager
android:id="@+id/vp_home"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/white"
app:tl_iconHeight="23dp"
app:tl_iconWidth="23dp"
app:tl_indicator_color="#2C97DE"
app:tl_indicator_height="0dp"
app:tl_textSelectColor="@color/main_tab_text_checked"
app:tl_textUnselectColor="@color/main_tab_text_uncheck"
app:tl_textsize="12sp"
app:tl_underline_color="#DDDDDD"
app:tl_underline_height="1dp" />
android:layout_height="0dp"
android:layout_weight="1"
android:background="@color/white" />
<View
android:id="@+id/lineView"
android:layout_above="@+id/ctl_table"
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_height="1dp"
android:background="@color/divider_gray" />
<androidx.viewpager.widget.ViewPager
android:layout_above="@+id/lineView"
android:id="@+id/vp_home"
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white" />
android:layout_height="55dp"
android:background="@color/white"
app:tabGravity="fill"
app:tabIndicatorFullWidth="false"
app:tabIndicatorGravity="center"
app:tabIndicatorHeight="0dp"
app:tabMaxWidth="0dp"
app:tabMode="fixed"
app:tabRippleColor="@android:color/transparent"
app:tabSelectedTextColor="@color/main_tab_text_checked"
app:tabTextColor="@color/main_tab_text_uncheck" />
</RelativeLayout>
</LinearLayout>

View File

@ -7,7 +7,6 @@
android:background="@color/white"
tools:context=".ui.guide.SplashActivity">
<ImageView
android:id="@+id/image_logo"
android:layout_width="160dp"
@ -48,23 +47,23 @@
app:layout_constraintTop_toBottomOf="@+id/title" />
<com.mindspore.customview.countdown.CountDownView
<com.mindspore.customview.countdown.MSCountDownView
android:id="@+id/cdv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="40dp"
android:layout_marginEnd="20dp"
app:cd_animator_time="3"
app:cd_animator_time_unit="@string/splash_count_down"
app:cd_arc_color="@color/btn_small_checked"
app:cd_arc_width="2dp"
app:cd_bg_color="@color/gray_light"
app:cd_circle_radius="20dp"
app:cd_location="top"
app:cd_retreat_type="forward"
app:cd_text_color="@color/black"
app:cd_text_size="12sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintTop_toTopOf="parent"
app:ms_cd_animator_time="3"
app:ms_cd_animator_time_unit="@string/splash_count_down"
app:ms_cd_arc_color="@color/btn_small_checked"
app:ms_cd_arc_width="2dp"
app:ms_cd_bg_color="@color/gray_light"
app:ms_cd_circle_radius="20dp"
app:ms_cd_location="top"
app:ms_cd_retreat_type="forward"
app:ms_cd_text_color="@color/black"
app:ms_cd_text_size="12sp" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false">
<LinearLayout
android:id="@+id/ll_tap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/tab_icon"
android:layout_width="23dp"
android:layout_height="23dp"/>
<TextView
android:textSize="12sp"
android:id="@+id/tab_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"/>
</LinearLayout>
</RelativeLayout>

View File

@ -1,253 +0,0 @@
/**
* Copyright 2021 Huawei Technologies Co., Ltd
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mindspore.customview.countdown;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.os.Build;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import com.mindspore.customview.R;
public class CountDownView extends View {
private Context mContext;//上下文
private Paint mPaintBackGround;//背景画笔
private Paint mPaintArc;//圆弧画笔
private Paint mPaintText;//文字画笔
private int mRetreatType;//圆弧绘制方式增加和减少
private float mPaintArcWidth;//最外层圆弧的宽度
private int mCircleRadius;//圆圈的半径
private int mPaintArcColor = Color.parseColor("#3C3F41");//初始值
private int mPaintBackGroundColor = Color.parseColor("#55B2E5");//初始值
private int mLoadingTime;//时间单位秒
private String mLoadingTimeUnit = "";//时间单位
private int mTextColor = Color.BLACK;//字体颜色
private int mTextSize;//字体大小
private int location;//从哪个位置开始
private float startAngle;//开始角度
private float mmSweepAngleStart;//起点
private float mmSweepAngleEnd;//终点
private float mSweepAngle;//扫过的角度
private String mText = "";//要绘制的文字
private int mWidth;
private int mHeight;
private AnimatorSet set;
public CountDownView(Context context) {
this(context, null);
}
public CountDownView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public CountDownView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CountDownView);
mRetreatType = array.getInt(R.styleable.CountDownView_cd_retreat_type, 1);
location = array.getInt(R.styleable.CountDownView_cd_location, 1);
mCircleRadius = (int) array.getDimension(R.styleable.CountDownView_cd_circle_radius, dip2px(context, 25));//默认25dp
mPaintArcWidth = array.getDimension(R.styleable.CountDownView_cd_arc_width, dip2px(context, 3));//默认3dp
mPaintArcColor = array.getColor(R.styleable.CountDownView_cd_arc_color, mPaintArcColor);
mTextSize = (int) array.getDimension(R.styleable.CountDownView_cd_text_size, dip2px(context, 14));//默认14sp
mTextColor = array.getColor(R.styleable.CountDownView_cd_text_color, mTextColor);
mPaintBackGroundColor = array.getColor(R.styleable.CountDownView_cd_bg_color, mPaintBackGroundColor);
mLoadingTime = array.getInteger(R.styleable.CountDownView_cd_animator_time, 3);//默认3秒
mLoadingTimeUnit = array.getString(R.styleable.CountDownView_cd_animator_time_unit);//时间单位
if (TextUtils.isEmpty(mLoadingTimeUnit)) {
mLoadingTimeUnit = "";
}
array.recycle();
init();
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void init() {
//背景设为透明然后造成圆形View的视觉错觉
this.setBackground(ContextCompat.getDrawable(mContext, android.R.color.transparent));
mPaintBackGround = new Paint();
mPaintBackGround.setStyle(Paint.Style.FILL);
mPaintBackGround.setAntiAlias(true);
mPaintBackGround.setColor(mPaintBackGroundColor);
mPaintArc = new Paint();
mPaintArc.setStyle(Paint.Style.STROKE);
mPaintArc.setAntiAlias(true);
mPaintArc.setColor(mPaintArcColor);
mPaintArc.setStrokeWidth(mPaintArcWidth);
mPaintText = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintText.setStyle(Paint.Style.STROKE);
mPaintText.setStyle(Paint.Style.FILL);
mPaintText.setAntiAlias(true);
mPaintText.setColor(mTextColor);
mPaintText.setTextSize(mTextSize);
//如果时间为小于0则默认倒计时时间为3秒
if (mLoadingTime < 0) {
mLoadingTime = 3;
}
if (location == 1) {//默认从左侧开始
startAngle = -180;
} else if (location == 2) {
startAngle = -90;
} else if (location == 3) {
startAngle = 0;
} else if (location == 4) {
startAngle = 90;
}
if (mRetreatType == 1) {
mmSweepAngleStart = 0f;
mmSweepAngleEnd = 360f;
} else {
mmSweepAngleStart = 360f;
mmSweepAngleEnd = 0f;
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//获取view宽高
mWidth = w;
mHeight = h;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//因为必须是圆形的view所以在这里重新赋值
setMeasuredDimension(mCircleRadius * 2, mCircleRadius * 2);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画北景园
canvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2 - mPaintArcWidth, mPaintBackGround);
//画圆弧
RectF rectF = new RectF(0 + mPaintArcWidth / 2, 0 + mPaintArcWidth / 2, mWidth - mPaintArcWidth / 2, mHeight - mPaintArcWidth / 2);
canvas.drawArc(rectF, startAngle, mSweepAngle, false, mPaintArc);
//画文字
float mTextWidth = mPaintText.measureText(mText, 0, mText.length());
float dx = mWidth / 2 - mTextWidth / 2;
Paint.FontMetricsInt fontMetricsInt = mPaintText.getFontMetricsInt();
float dy = (fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom;
float baseLine = mHeight / 2 + dy;
canvas.drawText(mText, dx, baseLine, mPaintText);
}
/**
* 开始动态倒计时
*/
public void start() {
ValueAnimator animator = ValueAnimator.ofFloat(mmSweepAngleStart, mmSweepAngleEnd);
animator.setInterpolator(new LinearInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mSweepAngle = (float) valueAnimator.getAnimatedValue();
//获取到需要绘制的角度重新绘制
invalidate();
}
});
//这里是时间获取和赋值
ValueAnimator animator1 = ValueAnimator.ofInt(mLoadingTime, 0);
animator1.setInterpolator(new LinearInterpolator());
animator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int time = (int) valueAnimator.getAnimatedValue();
mText = time + mLoadingTimeUnit;
}
});
set = new AnimatorSet();
set.playTogether(animator, animator1);
set.setDuration(mLoadingTime * 1000);
set.setInterpolator(new LinearInterpolator());
set.start();
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
clearAnimation();
if (loadingFinishListener != null) {
loadingFinishListener.finish();
}
}
});
}
/**
* 停止动画
*/
public void stop() {
loadingFinishListener = null;
if (set != null && set.isRunning()) {
set.cancel();
}
}
/**
* 设置倒计时时间
*
* @param time 时间
*/
public void setTime(int time) {
mLoadingTime = time;
}
private OnLoadingFinishListener loadingFinishListener;
public void setOnLoadingFinishListener(OnLoadingFinishListener listener) {
this.loadingFinishListener = listener;
}
public interface OnLoadingFinishListener {
void finish();
}
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}

View File

@ -0,0 +1,227 @@
/**
* Copyright 2021 Huawei Technologies Co., Ltd
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mindspore.customview.countdown;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Build;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import com.mindspore.common.utils.DisplayUtil;
import com.mindspore.customview.R;
public class MSCountDownView extends View {
private static final int HALF = 2;
private Context mContext;
private Paint mPaintBackGround, mPaintArc, mPaintText;
private int mRetreatType;
private float mPaintArcWidth;
private int mCircleRadius;
private int mPaintArcColor = Color.RED;
private int mPaintBackGroundColor = Color.BLUE;
private int mLoadingTime;
private String mLoadingTimeUnit = "";
private int mTextColor = Color.BLACK;
private int mTextSize;
private int location;
private float startAngle, mmSweepAngleStart, mmSweepAngleEnd, mSweepAngle;
private String mText = "";
private int mWidth, mHeight;
private AnimatorSet set;
public MSCountDownView(Context context) {
this(context, null);
}
public MSCountDownView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public MSCountDownView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
init(attrs);
initView();
}
private void init(AttributeSet attrs) {
TypedArray array = mContext.obtainStyledAttributes(attrs, R.styleable.MSCountDownView);
mRetreatType = array.getInt(R.styleable.MSCountDownView_ms_cd_retreat_type, 1);
location = array.getInt(R.styleable.MSCountDownView_ms_cd_location, 1);
mCircleRadius = (int) array.getDimension(R.styleable.MSCountDownView_ms_cd_circle_radius, DisplayUtil.dp2px(mContext, 25));
mPaintArcWidth = array.getDimension(R.styleable.MSCountDownView_ms_cd_arc_width, DisplayUtil.dp2px(mContext, 3));
mPaintArcColor = array.getColor(R.styleable.MSCountDownView_ms_cd_arc_color, mPaintArcColor);
mTextSize = (int) array.getDimension(R.styleable.MSCountDownView_ms_cd_text_size, DisplayUtil.dp2px(mContext, 14));
mTextColor = array.getColor(R.styleable.MSCountDownView_ms_cd_text_color, mTextColor);
mPaintBackGroundColor = array.getColor(R.styleable.MSCountDownView_ms_cd_bg_color, mPaintBackGroundColor);
mLoadingTime = array.getInteger(R.styleable.MSCountDownView_ms_cd_animator_time, 3);
mLoadingTimeUnit = array.getString(R.styleable.MSCountDownView_ms_cd_animator_time_unit);
if (TextUtils.isEmpty(mLoadingTimeUnit)) {
mLoadingTimeUnit = "";
}
array.recycle();
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void initView() {
this.setBackground(ContextCompat.getDrawable(mContext, android.R.color.transparent));
mPaintBackGround = new Paint();
mPaintBackGround.setAntiAlias(true);
mPaintBackGround.setStyle(Paint.Style.FILL);
mPaintBackGround.setColor(mPaintBackGroundColor);
mPaintArc = new Paint();
mPaintArc.setAntiAlias(true);
mPaintArc.setStyle(Paint.Style.STROKE);
mPaintArc.setColor(mPaintArcColor);
mPaintArc.setStrokeWidth(mPaintArcWidth);
mPaintText = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintText.setAntiAlias(true);
mPaintText.setStyle(Paint.Style.STROKE);
mPaintText.setStyle(Paint.Style.FILL);
mPaintText.setColor(mTextColor);
mPaintText.setTextSize(mTextSize);
if (mLoadingTime < 0) {
mLoadingTime = 3;
}
switch (location) {
case 1:
startAngle = -180;
break;
case 2:
startAngle = -90;
break;
case 3:
startAngle = 0;
break;
case 4:
startAngle = 90;
break;
}
if (mRetreatType == 1) {
mmSweepAngleStart = 0f;
mmSweepAngleEnd = 360f;
} else {
mmSweepAngleStart = 360f;
mmSweepAngleEnd = 0f;
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(mCircleRadius * HALF, mCircleRadius * HALF);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(mWidth / HALF, mHeight / HALF, mWidth / HALF - mPaintArcWidth, mPaintBackGround);
RectF rectF = new RectF( mPaintArcWidth / HALF, mPaintArcWidth / HALF, mWidth - mPaintArcWidth / HALF, mHeight - mPaintArcWidth / HALF);
canvas.drawArc(rectF, startAngle, mSweepAngle, false, mPaintArc);
float mTextWidth = mPaintText.measureText(mText, 0, mText.length());
float dx = mWidth / HALF - mTextWidth / HALF;
Paint.FontMetricsInt fontMetricsInt = mPaintText.getFontMetricsInt();
float dy = (fontMetricsInt.bottom - fontMetricsInt.top) / HALF - fontMetricsInt.bottom;
float baseLine = mHeight / HALF + dy;
canvas.drawText(mText, dx, baseLine, mPaintText);
}
public void start() {
ValueAnimator viewAnimator = ValueAnimator.ofFloat(mmSweepAngleStart, mmSweepAngleEnd);
viewAnimator.setInterpolator(new LinearInterpolator());
viewAnimator.addUpdateListener(valueAnimator -> {
mSweepAngle = (float) valueAnimator.getAnimatedValue();
invalidate();
});
ValueAnimator textAnimator = ValueAnimator.ofInt(mLoadingTime, 0);
textAnimator.setInterpolator(new LinearInterpolator());
textAnimator.addUpdateListener(valueAnimator -> {
int time = (int) valueAnimator.getAnimatedValue();
mText = time + mLoadingTimeUnit;
});
set = new AnimatorSet();
set.setDuration(mLoadingTime * 1000);
set.playTogether(viewAnimator, textAnimator);
set.setInterpolator(new LinearInterpolator());
set.start();
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
clearAnimation();
if (onCountDownFinishListener != null) {
onCountDownFinishListener.finish();
}
}
});
}
public void stop() {
onCountDownFinishListener = null;
if (set != null && set.isRunning()) {
set.cancel();
}
}
public void setTime(int time) {
mLoadingTime = time;
}
private OnCountDownFinishListener onCountDownFinishListener;
public void setOnLoadingFinishListener(OnCountDownFinishListener listener) {
this.onCountDownFinishListener = listener;
}
public interface OnCountDownFinishListener {
void finish();
}
}

View File

@ -1,943 +0,0 @@
/**
* Copyright 2021 Huawei Technologies Co., Ltd
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mindspore.customview.tablayout;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.OvershootInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import com.mindspore.common.utils.DisplayUtil;
import com.mindspore.customview.R;
import com.mindspore.customview.tablayout.listener.CustomTabEntity;
import com.mindspore.customview.tablayout.listener.OnTabSelectListener;
import com.mindspore.customview.tablayout.utils.FragmentChangeManager;
import com.mindspore.customview.tablayout.utils.UnreadMsgUtils;
import com.mindspore.customview.tablayout.widget.MsgView;
import java.util.ArrayList;
public class CommonTabLayout extends FrameLayout implements ValueAnimator.AnimatorUpdateListener {
private Context mContext;
private ArrayList<CustomTabEntity> mTabEntitys = new ArrayList<>();
private LinearLayout mTabsContainer;
private int mCurrentTab;
private int mLastTab;
private int mTabCount;
private final Rect mIndicatorRect = new Rect();
private final GradientDrawable mIndicatorDrawable = new GradientDrawable();
private Paint mRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint mDividerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint mTrianglePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Path mTrianglePath = new Path();
private static final int STYLE_NORMAL = 0;
private static final int STYLE_TRIANGLE = 1;
private static final int STYLE_BLOCK = 2;
private int mIndicatorStyle = STYLE_NORMAL;
private float mTabPadding;
private boolean mTabSpaceEqual;
private float mTabWidth;
/**
* indicator
*/
private int mIndicatorColor;
private float mIndicatorHeight;
private float mIndicatorWidth;
private float mIndicatorCornerRadius;
private float mIndicatorMarginLeft;
private float mIndicatorMarginTop;
private float mIndicatorMarginRight;
private float mIndicatorMarginBottom;
private long mIndicatorAnimDuration;
private boolean mIndicatorAnimEnable;
private boolean mIndicatorBounceEnable;
private int mIndicatorGravity;
/**
* underline
*/
private int mUnderlineColor;
private float mUnderlineHeight;
private int mUnderlineGravity;
/**
* divider
*/
private int mDividerColor;
private float mDividerWidth;
private float mDividerPadding;
/**
* title
*/
private static final int TEXT_BOLD_NONE = 0;
private static final int TEXT_BOLD_WHEN_SELECT = 1;
private static final int TEXT_BOLD_BOTH = 2;
private float mTextsize;
private int mTextSelectColor;
private int mTextUnselectColor;
private int mTextBold;
private boolean mTextAllCaps;
/**
* icon
*/
private boolean mIconVisible;
private int mIconGravity;
private float mIconWidth;
private float mIconHeight;
private float mIconMargin;
private int mHeight;
/**
* anim
*/
private ValueAnimator mValueAnimator;
private OvershootInterpolator mInterpolator = new OvershootInterpolator(1.5f);
private FragmentChangeManager mFragmentChangeManager;
public CommonTabLayout(Context context) {
this(context, null, 0);
}
public CommonTabLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CommonTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setWillNotDraw(false);
setClipChildren(false);
setClipToPadding(false);
this.mContext = context;
mTabsContainer = new LinearLayout(context);
addView(mTabsContainer);
obtainAttributes(context, attrs);
//get layout_height
String height = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "layout_height");
//create ViewPager
if (height.equals(ViewGroup.LayoutParams.MATCH_PARENT + "")) {
} else if (height.equals(ViewGroup.LayoutParams.WRAP_CONTENT + "")) {
} else {
int[] systemAttrs = {android.R.attr.layout_height};
TypedArray a = context.obtainStyledAttributes(attrs, systemAttrs);
mHeight = a.getDimensionPixelSize(0, ViewGroup.LayoutParams.WRAP_CONTENT);
a.recycle();
}
mValueAnimator = ValueAnimator.ofObject(new PointEvaluator(), mLastP, mCurrentP);
mValueAnimator.addUpdateListener(this);
}
private void obtainAttributes(Context context, AttributeSet attrs) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CommonTabLayout);
mIndicatorStyle = ta.getInt(R.styleable.CommonTabLayout_tl_indicator_style, 0);
mIndicatorColor = ta.getColor(R.styleable.CommonTabLayout_tl_indicator_color, Color.parseColor(mIndicatorStyle == STYLE_BLOCK ? "#4B6A87" : "#ffffff"));
mIndicatorHeight = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_height,
DisplayUtil.dp2px(context, mIndicatorStyle == STYLE_TRIANGLE ? 4 : (mIndicatorStyle == STYLE_BLOCK ? -1 : 2)));
mIndicatorWidth = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_width, DisplayUtil.dp2px(context, mIndicatorStyle == STYLE_TRIANGLE ? 10 : -1));
mIndicatorCornerRadius = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_corner_radius, DisplayUtil.dp2px(context, mIndicatorStyle == STYLE_BLOCK ? -1 : 0));
mIndicatorMarginLeft = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_margin_left, DisplayUtil.dp2px(context, 0));
mIndicatorMarginTop = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_margin_top, DisplayUtil.dp2px(context, mIndicatorStyle == STYLE_BLOCK ? 7 : 0));
mIndicatorMarginRight = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_margin_right, DisplayUtil.dp2px(context, 0));
mIndicatorMarginBottom = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_margin_bottom, DisplayUtil.dp2px(context, mIndicatorStyle == STYLE_BLOCK ? 7 : 0));
mIndicatorAnimEnable = ta.getBoolean(R.styleable.CommonTabLayout_tl_indicator_anim_enable, true);
mIndicatorBounceEnable = ta.getBoolean(R.styleable.CommonTabLayout_tl_indicator_bounce_enable, true);
mIndicatorAnimDuration = ta.getInt(R.styleable.CommonTabLayout_tl_indicator_anim_duration, -1);
mIndicatorGravity = ta.getInt(R.styleable.CommonTabLayout_tl_indicator_gravity, Gravity.BOTTOM);
mUnderlineColor = ta.getColor(R.styleable.CommonTabLayout_tl_underline_color, Color.parseColor("#ffffff"));
mUnderlineHeight = ta.getDimension(R.styleable.CommonTabLayout_tl_underline_height, DisplayUtil.dp2px(context, 0));
mUnderlineGravity = ta.getInt(R.styleable.CommonTabLayout_tl_underline_gravity, Gravity.BOTTOM);
mDividerColor = ta.getColor(R.styleable.CommonTabLayout_tl_divider_color, Color.parseColor("#ffffff"));
mDividerWidth = ta.getDimension(R.styleable.CommonTabLayout_tl_divider_width, DisplayUtil.dp2px(context, 0));
mDividerPadding = ta.getDimension(R.styleable.CommonTabLayout_tl_divider_padding, DisplayUtil.dp2px(context, 12));
mTextsize = ta.getDimension(R.styleable.CommonTabLayout_tl_textsize, DisplayUtil.sp2px(context, 13f));
mTextSelectColor = ta.getColor(R.styleable.CommonTabLayout_tl_textSelectColor, Color.parseColor("#ffffff"));
mTextUnselectColor = ta.getColor(R.styleable.CommonTabLayout_tl_textUnselectColor, Color.parseColor("#AAffffff"));
mTextBold = ta.getInt(R.styleable.CommonTabLayout_tl_textBold, TEXT_BOLD_NONE);
mTextAllCaps = ta.getBoolean(R.styleable.CommonTabLayout_tl_textAllCaps, false);
mIconVisible = ta.getBoolean(R.styleable.CommonTabLayout_tl_iconVisible, true);
mIconGravity = ta.getInt(R.styleable.CommonTabLayout_tl_iconGravity, Gravity.TOP);
mIconWidth = ta.getDimension(R.styleable.CommonTabLayout_tl_iconWidth, DisplayUtil.dp2px(context, 0));
mIconHeight = ta.getDimension(R.styleable.CommonTabLayout_tl_iconHeight, DisplayUtil.dp2px(context, 0));
mIconMargin = ta.getDimension(R.styleable.CommonTabLayout_tl_iconMargin, DisplayUtil.dp2px(context, 2.5f));
mTabSpaceEqual = ta.getBoolean(R.styleable.CommonTabLayout_tl_tab_space_equal, true);
mTabWidth = ta.getDimension(R.styleable.CommonTabLayout_tl_tab_width, DisplayUtil.dp2px(context, -1));
mTabPadding = ta.getDimension(R.styleable.CommonTabLayout_tl_tab_padding, mTabSpaceEqual || mTabWidth > 0 ? DisplayUtil.dp2px(context, 0) : DisplayUtil.dp2px(context, 10));
ta.recycle();
}
public void setTabData(ArrayList<CustomTabEntity> tabEntitys) {
if (tabEntitys == null || tabEntitys.size() == 0) {
throw new IllegalStateException("TabEntitys can not be NULL or EMPTY !");
}
this.mTabEntitys.clear();
this.mTabEntitys.addAll(tabEntitys);
notifyDataSetChanged();
}
public void setTabData(ArrayList<CustomTabEntity> tabEntitys, FragmentActivity fa, int containerViewId, ArrayList<Fragment> fragments) {
mFragmentChangeManager = new FragmentChangeManager(fa.getSupportFragmentManager(), containerViewId, fragments);
setTabData(tabEntitys);
}
public void notifyDataSetChanged() {
mTabsContainer.removeAllViews();
this.mTabCount = mTabEntitys.size();
View tabView;
for (int i = 0; i < mTabCount; i++) {
if (mIconGravity == Gravity.LEFT) {
tabView = View.inflate(mContext, R.layout.layout_tab_left, null);
} else if (mIconGravity == Gravity.RIGHT) {
tabView = View.inflate(mContext, R.layout.layout_tab_right, null);
} else if (mIconGravity == Gravity.BOTTOM) {
tabView = View.inflate(mContext, R.layout.layout_tab_bottom, null);
} else {
tabView = View.inflate(mContext, R.layout.layout_tab_top, null);
}
tabView.setTag(i);
addTab(i, tabView);
}
updateTabStyles();
}
private void addTab(final int position, View tabView) {
TextView tv_tab_title = tabView.findViewById(R.id.tv_tab_title);
tv_tab_title.setText(mTabEntitys.get(position).getTabTitle());
ImageView iv_tab_icon = tabView.findViewById(R.id.iv_tab_icon);
iv_tab_icon.setImageResource(mTabEntitys.get(position).getTabUnselectedIcon());
tabView.setOnClickListener(v -> {
int position1 = (Integer) v.getTag();
if (mCurrentTab != position1) {
setCurrentTab(position1);
if (mListener != null) {
mListener.onTabSelect(position1);
}
} else {
if (mListener != null) {
mListener.onTabReselect(position1);
}
}
});
LinearLayout.LayoutParams lp_tab = mTabSpaceEqual ?
new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f) :
new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
if (mTabWidth > 0) {
lp_tab = new LinearLayout.LayoutParams((int) mTabWidth, LayoutParams.MATCH_PARENT);
}
mTabsContainer.addView(tabView, position, lp_tab);
}
private void updateTabStyles() {
for (int i = 0; i < mTabCount; i++) {
View tabView = mTabsContainer.getChildAt(i);
tabView.setPadding((int) mTabPadding, 0, (int) mTabPadding, 0);
TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
tv_tab_title.setTextColor(i == mCurrentTab ? mTextSelectColor : mTextUnselectColor);
tv_tab_title.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextsize);
if (mTextAllCaps) {
tv_tab_title.setText(tv_tab_title.getText().toString().toUpperCase());
}
if (mTextBold == TEXT_BOLD_BOTH) {
tv_tab_title.getPaint().setFakeBoldText(true);
} else if (mTextBold == TEXT_BOLD_NONE) {
tv_tab_title.getPaint().setFakeBoldText(false);
}
ImageView iv_tab_icon = (ImageView) tabView.findViewById(R.id.iv_tab_icon);
if (mIconVisible) {
iv_tab_icon.setVisibility(View.VISIBLE);
CustomTabEntity tabEntity = mTabEntitys.get(i);
iv_tab_icon.setImageResource(i == mCurrentTab ? tabEntity.getTabSelectedIcon() : tabEntity.getTabUnselectedIcon());
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
mIconWidth <= 0 ? LinearLayout.LayoutParams.WRAP_CONTENT : (int) mIconWidth,
mIconHeight <= 0 ? LinearLayout.LayoutParams.WRAP_CONTENT : (int) mIconHeight);
if (mIconGravity == Gravity.LEFT) {
lp.rightMargin = (int) mIconMargin;
} else if (mIconGravity == Gravity.RIGHT) {
lp.leftMargin = (int) mIconMargin;
} else if (mIconGravity == Gravity.BOTTOM) {
lp.topMargin = (int) mIconMargin;
} else {
lp.bottomMargin = (int) mIconMargin;
}
iv_tab_icon.setLayoutParams(lp);
} else {
iv_tab_icon.setVisibility(View.GONE);
}
}
}
private void updateTabSelection(int position) {
for (int i = 0; i < mTabCount; ++i) {
View tabView = mTabsContainer.getChildAt(i);
final boolean isSelect = i == position;
TextView tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
tab_title.setTextColor(isSelect ? mTextSelectColor : mTextUnselectColor);
ImageView iv_tab_icon = (ImageView) tabView.findViewById(R.id.iv_tab_icon);
CustomTabEntity tabEntity = mTabEntitys.get(i);
iv_tab_icon.setImageResource(isSelect ? tabEntity.getTabSelectedIcon() : tabEntity.getTabUnselectedIcon());
if (mTextBold == TEXT_BOLD_WHEN_SELECT) {
tab_title.getPaint().setFakeBoldText(isSelect);
}
}
}
private void calcOffset() {
final View currentTabView = mTabsContainer.getChildAt(this.mCurrentTab);
mCurrentP.left = currentTabView.getLeft();
mCurrentP.right = currentTabView.getRight();
final View lastTabView = mTabsContainer.getChildAt(this.mLastTab);
mLastP.left = lastTabView.getLeft();
mLastP.right = lastTabView.getRight();
if (mLastP.left == mCurrentP.left && mLastP.right == mCurrentP.right) {
invalidate();
} else {
mValueAnimator.setObjectValues(mLastP, mCurrentP);
if (mIndicatorBounceEnable) {
mValueAnimator.setInterpolator(mInterpolator);
}
if (mIndicatorAnimDuration < 0) {
mIndicatorAnimDuration = mIndicatorBounceEnable ? 500 : 250;
}
mValueAnimator.setDuration(mIndicatorAnimDuration);
mValueAnimator.start();
}
}
private void calcIndicatorRect() {
View currentTabView = mTabsContainer.getChildAt(this.mCurrentTab);
float left = currentTabView.getLeft();
float right = currentTabView.getRight();
mIndicatorRect.left = (int) left;
mIndicatorRect.right = (int) right;
if (mIndicatorWidth < 0) {
} else {
float indicatorLeft = currentTabView.getLeft() + (currentTabView.getWidth() - mIndicatorWidth) / 2;
mIndicatorRect.left = (int) indicatorLeft;
mIndicatorRect.right = (int) (mIndicatorRect.left + mIndicatorWidth);
}
}
@Override
public void onAnimationUpdate(ValueAnimator animation) {
View currentTabView = mTabsContainer.getChildAt(this.mCurrentTab);
IndicatorPoint p = (IndicatorPoint) animation.getAnimatedValue();
mIndicatorRect.left = (int) p.left;
mIndicatorRect.right = (int) p.right;
if (mIndicatorWidth < 0) {
} else {
float indicatorLeft = p.left + (currentTabView.getWidth() - mIndicatorWidth) / 2;
mIndicatorRect.left = (int) indicatorLeft;
mIndicatorRect.right = (int) (mIndicatorRect.left + mIndicatorWidth);
}
invalidate();
}
private boolean mIsFirstDraw = true;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isInEditMode() || mTabCount <= 0) {
return;
}
int height = getHeight();
int paddingLeft = getPaddingLeft();
// draw divider
if (mDividerWidth > 0) {
mDividerPaint.setStrokeWidth(mDividerWidth);
mDividerPaint.setColor(mDividerColor);
for (int i = 0; i < mTabCount - 1; i++) {
View tab = mTabsContainer.getChildAt(i);
canvas.drawLine(paddingLeft + tab.getRight(), mDividerPadding, paddingLeft + tab.getRight(), height - mDividerPadding, mDividerPaint);
}
}
// draw underline
if (mUnderlineHeight > 0) {
mRectPaint.setColor(mUnderlineColor);
if (mUnderlineGravity == Gravity.BOTTOM) {
canvas.drawRect(paddingLeft, height - mUnderlineHeight, mTabsContainer.getWidth() + paddingLeft, height, mRectPaint);
} else {
canvas.drawRect(paddingLeft, 0, mTabsContainer.getWidth() + paddingLeft, mUnderlineHeight, mRectPaint);
}
}
//draw indicator line
if (mIndicatorAnimEnable) {
if (mIsFirstDraw) {
mIsFirstDraw = false;
calcIndicatorRect();
}
} else {
calcIndicatorRect();
}
if (mIndicatorStyle == STYLE_TRIANGLE) {
if (mIndicatorHeight > 0) {
mTrianglePaint.setColor(mIndicatorColor);
mTrianglePath.reset();
mTrianglePath.moveTo(paddingLeft + mIndicatorRect.left, height);
mTrianglePath.lineTo(paddingLeft + mIndicatorRect.left / 2 + mIndicatorRect.right / 2, height - mIndicatorHeight);
mTrianglePath.lineTo(paddingLeft + mIndicatorRect.right, height);
mTrianglePath.close();
canvas.drawPath(mTrianglePath, mTrianglePaint);
}
} else if (mIndicatorStyle == STYLE_BLOCK) {
if (mIndicatorHeight < 0) {
mIndicatorHeight = height - mIndicatorMarginTop - mIndicatorMarginBottom;
} else {
}
if (mIndicatorHeight > 0) {
if (mIndicatorCornerRadius < 0 || mIndicatorCornerRadius > mIndicatorHeight / 2) {
mIndicatorCornerRadius = mIndicatorHeight / 2;
}
mIndicatorDrawable.setColor(mIndicatorColor);
mIndicatorDrawable.setBounds(paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,
(int) mIndicatorMarginTop, (int) (paddingLeft + mIndicatorRect.right - mIndicatorMarginRight),
(int) (mIndicatorMarginTop + mIndicatorHeight));
mIndicatorDrawable.setCornerRadius(mIndicatorCornerRadius);
mIndicatorDrawable.draw(canvas);
}
} else {
if (mIndicatorHeight > 0) {
mIndicatorDrawable.setColor(mIndicatorColor);
if (mIndicatorGravity == Gravity.BOTTOM) {
mIndicatorDrawable.setBounds(paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,
height - (int) mIndicatorHeight - (int) mIndicatorMarginBottom,
paddingLeft + mIndicatorRect.right - (int) mIndicatorMarginRight,
height - (int) mIndicatorMarginBottom);
} else {
mIndicatorDrawable.setBounds(paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,
(int) mIndicatorMarginTop,
paddingLeft + mIndicatorRect.right - (int) mIndicatorMarginRight,
(int) mIndicatorHeight + (int) mIndicatorMarginTop);
}
mIndicatorDrawable.setCornerRadius(mIndicatorCornerRadius);
mIndicatorDrawable.draw(canvas);
}
}
}
//setter and getter
public void setCurrentTab(int currentTab) {
mLastTab = this.mCurrentTab;
this.mCurrentTab = currentTab;
updateTabSelection(currentTab);
if (mFragmentChangeManager != null) {
mFragmentChangeManager.setFragments(currentTab);
}
if (mIndicatorAnimEnable) {
calcOffset();
} else {
invalidate();
}
}
public void setIndicatorStyle(int indicatorStyle) {
this.mIndicatorStyle = indicatorStyle;
invalidate();
}
public void setTabPadding(float tabPadding) {
this.mTabPadding = DisplayUtil.dp2px(mContext, tabPadding);
updateTabStyles();
}
public void setTabSpaceEqual(boolean tabSpaceEqual) {
this.mTabSpaceEqual = tabSpaceEqual;
updateTabStyles();
}
public void setTabWidth(float tabWidth) {
this.mTabWidth = DisplayUtil.dp2px(mContext, tabWidth);
updateTabStyles();
}
public void setIndicatorColor(int indicatorColor) {
this.mIndicatorColor = indicatorColor;
invalidate();
}
public void setIndicatorHeight(float indicatorHeight) {
this.mIndicatorHeight = DisplayUtil.dp2px(mContext, indicatorHeight);
invalidate();
}
public void setIndicatorWidth(float indicatorWidth) {
this.mIndicatorWidth = DisplayUtil.dp2px(mContext, indicatorWidth);
invalidate();
}
public void setIndicatorCornerRadius(float indicatorCornerRadius) {
this.mIndicatorCornerRadius = DisplayUtil.dp2px(mContext, indicatorCornerRadius);
invalidate();
}
public void setIndicatorGravity(int indicatorGravity) {
this.mIndicatorGravity = indicatorGravity;
invalidate();
}
public void setIndicatorMargin(float indicatorMarginLeft, float indicatorMarginTop,
float indicatorMarginRight, float indicatorMarginBottom) {
this.mIndicatorMarginLeft = DisplayUtil.dp2px(mContext, indicatorMarginLeft);
this.mIndicatorMarginTop = DisplayUtil.dp2px(mContext, indicatorMarginTop);
this.mIndicatorMarginRight = DisplayUtil.dp2px(mContext, indicatorMarginRight);
this.mIndicatorMarginBottom = DisplayUtil.dp2px(mContext, indicatorMarginBottom);
invalidate();
}
public void setIndicatorAnimDuration(long indicatorAnimDuration) {
this.mIndicatorAnimDuration = indicatorAnimDuration;
}
public void setIndicatorAnimEnable(boolean indicatorAnimEnable) {
this.mIndicatorAnimEnable = indicatorAnimEnable;
}
public void setIndicatorBounceEnable(boolean indicatorBounceEnable) {
this.mIndicatorBounceEnable = indicatorBounceEnable;
}
public void setUnderlineColor(int underlineColor) {
this.mUnderlineColor = underlineColor;
invalidate();
}
public void setUnderlineHeight(float underlineHeight) {
this.mUnderlineHeight = DisplayUtil.dp2px(mContext, underlineHeight);
invalidate();
}
public void setUnderlineGravity(int underlineGravity) {
this.mUnderlineGravity = underlineGravity;
invalidate();
}
public void setDividerColor(int dividerColor) {
this.mDividerColor = dividerColor;
invalidate();
}
public void setDividerWidth(float dividerWidth) {
this.mDividerWidth = DisplayUtil.dp2px(mContext, dividerWidth);
invalidate();
}
public void setDividerPadding(float dividerPadding) {
this.mDividerPadding = DisplayUtil.dp2px(mContext, dividerPadding);
invalidate();
}
public void setTextsize(float textsize) {
this.mTextsize = DisplayUtil.sp2px(mContext, textsize);
updateTabStyles();
}
public void setTextSelectColor(int textSelectColor) {
this.mTextSelectColor = textSelectColor;
updateTabStyles();
}
public void setTextUnselectColor(int textUnselectColor) {
this.mTextUnselectColor = textUnselectColor;
updateTabStyles();
}
public void setTextBold(int textBold) {
this.mTextBold = textBold;
updateTabStyles();
}
public void setIconVisible(boolean iconVisible) {
this.mIconVisible = iconVisible;
updateTabStyles();
}
public void setIconGravity(int iconGravity) {
this.mIconGravity = iconGravity;
notifyDataSetChanged();
}
public void setIconWidth(float iconWidth) {
this.mIconWidth = DisplayUtil.dp2px(mContext, iconWidth);
updateTabStyles();
}
public void setIconHeight(float iconHeight) {
this.mIconHeight = DisplayUtil.dp2px(mContext, iconHeight);
updateTabStyles();
}
public void setIconMargin(float iconMargin) {
this.mIconMargin = DisplayUtil.dp2px(mContext, iconMargin);
updateTabStyles();
}
public void setTextAllCaps(boolean textAllCaps) {
this.mTextAllCaps = textAllCaps;
updateTabStyles();
}
public int getTabCount() {
return mTabCount;
}
public int getCurrentTab() {
return mCurrentTab;
}
public int getIndicatorStyle() {
return mIndicatorStyle;
}
public float getTabPadding() {
return mTabPadding;
}
public boolean isTabSpaceEqual() {
return mTabSpaceEqual;
}
public float getTabWidth() {
return mTabWidth;
}
public int getIndicatorColor() {
return mIndicatorColor;
}
public float getIndicatorHeight() {
return mIndicatorHeight;
}
public float getIndicatorWidth() {
return mIndicatorWidth;
}
public float getIndicatorCornerRadius() {
return mIndicatorCornerRadius;
}
public float getIndicatorMarginLeft() {
return mIndicatorMarginLeft;
}
public float getIndicatorMarginTop() {
return mIndicatorMarginTop;
}
public float getIndicatorMarginRight() {
return mIndicatorMarginRight;
}
public float getIndicatorMarginBottom() {
return mIndicatorMarginBottom;
}
public long getIndicatorAnimDuration() {
return mIndicatorAnimDuration;
}
public boolean isIndicatorAnimEnable() {
return mIndicatorAnimEnable;
}
public boolean isIndicatorBounceEnable() {
return mIndicatorBounceEnable;
}
public int getUnderlineColor() {
return mUnderlineColor;
}
public float getUnderlineHeight() {
return mUnderlineHeight;
}
public int getDividerColor() {
return mDividerColor;
}
public float getDividerWidth() {
return mDividerWidth;
}
public float getDividerPadding() {
return mDividerPadding;
}
public float getTextsize() {
return mTextsize;
}
public int getTextSelectColor() {
return mTextSelectColor;
}
public int getTextUnselectColor() {
return mTextUnselectColor;
}
public int getTextBold() {
return mTextBold;
}
public boolean isTextAllCaps() {
return mTextAllCaps;
}
public int getIconGravity() {
return mIconGravity;
}
public float getIconWidth() {
return mIconWidth;
}
public float getIconHeight() {
return mIconHeight;
}
public float getIconMargin() {
return mIconMargin;
}
public boolean isIconVisible() {
return mIconVisible;
}
public ImageView getIconView(int tab) {
View tabView = mTabsContainer.getChildAt(tab);
ImageView iv_tab_icon = (ImageView) tabView.findViewById(R.id.iv_tab_icon);
return iv_tab_icon;
}
public TextView getTitleView(int tab) {
View tabView = mTabsContainer.getChildAt(tab);
TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
return tv_tab_title;
}
// show MsgTipView
private Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private SparseArray<Boolean> mInitSetMap = new SparseArray<>();
public void showMsg(int position, int num) {
if (position >= mTabCount) {
position = mTabCount - 1;
}
View tabView = mTabsContainer.getChildAt(position);
MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);
if (tipView != null) {
UnreadMsgUtils.show(tipView, num);
if (mInitSetMap.get(position) != null && mInitSetMap.get(position)) {
return;
}
if (!mIconVisible) {
setMsgMargin(position, 2, 2);
} else {
setMsgMargin(position, 0,
mIconGravity == Gravity.LEFT || mIconGravity == Gravity.RIGHT ? 4 : 0);
}
mInitSetMap.put(position, true);
}
}
public void showDot(int position) {
if (position >= mTabCount) {
position = mTabCount - 1;
}
showMsg(position, 0);
}
public void hideMsg(int position) {
if (position >= mTabCount) {
position = mTabCount - 1;
}
View tabView = mTabsContainer.getChildAt(position);
MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);
if (tipView != null) {
tipView.setVisibility(View.GONE);
}
}
public void setMsgMargin(int position, float leftPadding, float bottomPadding) {
if (position >= mTabCount) {
position = mTabCount - 1;
}
View tabView = mTabsContainer.getChildAt(position);
MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);
if (tipView != null) {
TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
mTextPaint.setTextSize(mTextsize);
float textWidth = mTextPaint.measureText(tv_tab_title.getText().toString());
float textHeight = mTextPaint.descent() - mTextPaint.ascent();
MarginLayoutParams lp = (MarginLayoutParams) tipView.getLayoutParams();
float iconH = mIconHeight;
float margin = 0;
if (mIconVisible) {
if (iconH <= 0) {
iconH = mContext.getResources().getDrawable(mTabEntitys.get(position).getTabSelectedIcon()).getIntrinsicHeight();
}
margin = mIconMargin;
}
if (mIconGravity == Gravity.TOP || mIconGravity == Gravity.BOTTOM) {
lp.leftMargin = DisplayUtil.dp2px(mContext, leftPadding);
lp.topMargin = mHeight > 0 ? (int) (mHeight - textHeight - iconH - margin) / 2 - DisplayUtil.dp2px(mContext, bottomPadding) : DisplayUtil.dp2px(mContext, bottomPadding);
} else {
lp.leftMargin = DisplayUtil.dp2px(mContext, leftPadding);
lp.topMargin = mHeight > 0 ? (int) (mHeight - Math.max(textHeight, iconH)) / 2 - DisplayUtil.dp2px(mContext, bottomPadding) : DisplayUtil.dp2px(mContext, bottomPadding);
}
tipView.setLayoutParams(lp);
}
}
public MsgView getMsgView(int position) {
if (position >= mTabCount) {
position = mTabCount - 1;
}
View tabView = mTabsContainer.getChildAt(position);
MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);
return tipView;
}
private OnTabSelectListener mListener;
public void setOnTabSelectListener(OnTabSelectListener listener) {
this.mListener = listener;
}
@Override
protected Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
bundle.putParcelable("instanceState", super.onSaveInstanceState());
bundle.putInt("mCurrentTab", mCurrentTab);
return bundle;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
Bundle bundle = (Bundle) state;
mCurrentTab = bundle.getInt("mCurrentTab");
state = bundle.getParcelable("instanceState");
if (mCurrentTab != 0 && mTabsContainer.getChildCount() > 0) {
updateTabSelection(mCurrentTab);
}
}
super.onRestoreInstanceState(state);
}
class IndicatorPoint {
public float left;
public float right;
}
private IndicatorPoint mCurrentP = new IndicatorPoint();
private IndicatorPoint mLastP = new IndicatorPoint();
class PointEvaluator implements TypeEvaluator<IndicatorPoint> {
@Override
public IndicatorPoint evaluate(float fraction, IndicatorPoint startValue, IndicatorPoint endValue) {
float left = startValue.left + fraction * (endValue.left - startValue.left);
float right = startValue.right + fraction * (endValue.right - startValue.right);
IndicatorPoint point = new IndicatorPoint();
point.left = left;
point.right = right;
return point;
}
}
}

View File

@ -1,749 +0,0 @@
/**
* Copyright 2021 Huawei Technologies Co., Ltd
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mindspore.customview.tablayout;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.OvershootInterpolator;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import com.mindspore.common.utils.DisplayUtil;
import com.mindspore.customview.R;
import com.mindspore.customview.tablayout.listener.OnTabSelectListener;
import com.mindspore.customview.tablayout.utils.FragmentChangeManager;
import com.mindspore.customview.tablayout.utils.UnreadMsgUtils;
import com.mindspore.customview.tablayout.widget.MsgView;
import java.util.ArrayList;
public class SegmentTabLayout extends FrameLayout implements ValueAnimator.AnimatorUpdateListener {
private Context mContext;
private String[] mTitles;
private LinearLayout mTabsContainer;
private int mCurrentTab;
private int mLastTab;
private int mTabCount;
private Rect mIndicatorRect = new Rect();
private GradientDrawable mIndicatorDrawable = new GradientDrawable();
private GradientDrawable mRectDrawable = new GradientDrawable();
private Paint mDividerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float mTabPadding;
private boolean mTabSpaceEqual;
private float mTabWidth;
/**
* indicator
*/
private int mIndicatorColor;
private float mIndicatorHeight;
private float mIndicatorCornerRadius;
private float mIndicatorMarginLeft;
private float mIndicatorMarginTop;
private float mIndicatorMarginRight;
private float mIndicatorMarginBottom;
private long mIndicatorAnimDuration;
private boolean mIndicatorAnimEnable;
private boolean mIndicatorBounceEnable;
/**
* divider
*/
private int mDividerColor;
private float mDividerWidth;
private float mDividerPadding;
/**
* title
*/
private static final int TEXT_BOLD_NONE = 0;
private static final int TEXT_BOLD_WHEN_SELECT = 1;
private static final int TEXT_BOLD_BOTH = 2;
private float mTextsize;
private int mTextSelectColor;
private int mTextUnselectColor;
private int mTextBold;
private boolean mTextAllCaps;
private int mBarColor;
private int mBarStrokeColor;
private float mBarStrokeWidth;
private int mHeight;
/**
* anim
*/
private ValueAnimator mValueAnimator;
private OvershootInterpolator mInterpolator = new OvershootInterpolator(0.8f);
private FragmentChangeManager mFragmentChangeManager;
private float[] mRadiusArr = new float[8];
public SegmentTabLayout(Context context) {
this(context, null, 0);
}
public SegmentTabLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SegmentTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setWillNotDraw(false);//重写onDraw方法,需要调用这个方法来清除flag
setClipChildren(false);
setClipToPadding(false);
this.mContext = context;
mTabsContainer = new LinearLayout(context);
addView(mTabsContainer);
obtainAttributes(context, attrs);
//get layout_height
String height = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "layout_height");
//create ViewPager
if (height.equals(ViewGroup.LayoutParams.MATCH_PARENT + "")) {
} else if (height.equals(ViewGroup.LayoutParams.WRAP_CONTENT + "")) {
} else {
int[] systemAttrs = {android.R.attr.layout_height};
TypedArray a = context.obtainStyledAttributes(attrs, systemAttrs);
mHeight = a.getDimensionPixelSize(0, ViewGroup.LayoutParams.WRAP_CONTENT);
a.recycle();
}
mValueAnimator = ValueAnimator.ofObject(new PointEvaluator(), mLastP, mCurrentP);
mValueAnimator.addUpdateListener(this);
}
private void obtainAttributes(Context context, AttributeSet attrs) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SegmentTabLayout);
mIndicatorColor = ta.getColor(R.styleable.SegmentTabLayout_tl_indicator_color, Color.parseColor("#222831"));
mIndicatorHeight = ta.getDimension(R.styleable.SegmentTabLayout_tl_indicator_height, -1);
mIndicatorCornerRadius = ta.getDimension(R.styleable.SegmentTabLayout_tl_indicator_corner_radius, -1);
mIndicatorMarginLeft = ta.getDimension(R.styleable.SegmentTabLayout_tl_indicator_margin_left, DisplayUtil.dp2px(context, 0));
mIndicatorMarginTop = ta.getDimension(R.styleable.SegmentTabLayout_tl_indicator_margin_top, 0);
mIndicatorMarginRight = ta.getDimension(R.styleable.SegmentTabLayout_tl_indicator_margin_right, DisplayUtil.dp2px(context, 0));
mIndicatorMarginBottom = ta.getDimension(R.styleable.SegmentTabLayout_tl_indicator_margin_bottom, 0);
mIndicatorAnimEnable = ta.getBoolean(R.styleable.SegmentTabLayout_tl_indicator_anim_enable, false);
mIndicatorBounceEnable = ta.getBoolean(R.styleable.SegmentTabLayout_tl_indicator_bounce_enable, true);
mIndicatorAnimDuration = ta.getInt(com.mindspore.customview.R.styleable.SegmentTabLayout_tl_indicator_anim_duration, -1);
mDividerColor = ta.getColor(R.styleable.SegmentTabLayout_tl_divider_color, mIndicatorColor);
mDividerWidth = ta.getDimension(R.styleable.SegmentTabLayout_tl_divider_width, DisplayUtil.dp2px(context, 1));
mDividerPadding = ta.getDimension(R.styleable.SegmentTabLayout_tl_divider_padding, 0);
mTextsize = ta.getDimension(R.styleable.SegmentTabLayout_tl_textsize, DisplayUtil.sp2px(context, 13f));
mTextSelectColor = ta.getColor(R.styleable.SegmentTabLayout_tl_textSelectColor, Color.parseColor("#ffffff"));
mTextUnselectColor = ta.getColor(R.styleable.SegmentTabLayout_tl_textUnselectColor, mIndicatorColor);
mTextBold = ta.getInt(R.styleable.SegmentTabLayout_tl_textBold, TEXT_BOLD_NONE);
mTextAllCaps = ta.getBoolean(R.styleable.SegmentTabLayout_tl_textAllCaps, false);
mTabSpaceEqual = ta.getBoolean(R.styleable.SegmentTabLayout_tl_tab_space_equal, true);
mTabWidth = ta.getDimension(R.styleable.SegmentTabLayout_tl_tab_width, DisplayUtil.dp2px(context, -1));
mTabPadding = ta.getDimension(R.styleable.SegmentTabLayout_tl_tab_padding, mTabSpaceEqual || mTabWidth > 0 ? DisplayUtil.dp2px(context, 0) : DisplayUtil.dp2px(context, 10));
mBarColor = ta.getColor(R.styleable.SegmentTabLayout_tl_bar_color, Color.TRANSPARENT);
mBarStrokeColor = ta.getColor(R.styleable.SegmentTabLayout_tl_bar_stroke_color, mIndicatorColor);
mBarStrokeWidth = ta.getDimension(R.styleable.SegmentTabLayout_tl_bar_stroke_width, DisplayUtil.dp2px(context, 1));
ta.recycle();
}
public void setTabData(String[] titles) {
if (titles == null || titles.length == 0) {
throw new IllegalStateException("Titles can not be NULL or EMPTY !");
}
this.mTitles = titles;
notifyDataSetChanged();
}
public void setTabData(String[] titles, FragmentActivity fa, int containerViewId, ArrayList<Fragment> fragments) {
mFragmentChangeManager = new FragmentChangeManager(fa.getSupportFragmentManager(), containerViewId, fragments);
setTabData(titles);
}
public void notifyDataSetChanged() {
mTabsContainer.removeAllViews();
this.mTabCount = mTitles.length;
View tabView;
for (int i = 0; i < mTabCount; i++) {
tabView = View.inflate(mContext, R.layout.layout_tab_segment, null);
tabView.setTag(i);
addTab(i, tabView);
}
updateTabStyles();
}
private void addTab(final int position, View tabView) {
TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
tv_tab_title.setText(mTitles[position]);
tabView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int position = (Integer) v.getTag();
if (mCurrentTab != position) {
setCurrentTab(position);
if (mListener != null) {
mListener.onTabSelect(position);
}
} else {
if (mListener != null) {
mListener.onTabReselect(position);
}
}
}
});
/** 每一个Tab的布局参数 */
LinearLayout.LayoutParams lp_tab = mTabSpaceEqual ?
new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f) :
new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
if (mTabWidth > 0) {
lp_tab = new LinearLayout.LayoutParams((int) mTabWidth, LayoutParams.MATCH_PARENT);
}
mTabsContainer.addView(tabView, position, lp_tab);
}
private void updateTabStyles() {
for (int i = 0; i < mTabCount; i++) {
View tabView = mTabsContainer.getChildAt(i);
tabView.setPadding((int) mTabPadding, 0, (int) mTabPadding, 0);
TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
tv_tab_title.setTextColor(i == mCurrentTab ? mTextSelectColor : mTextUnselectColor);
tv_tab_title.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextsize);
if (mTextAllCaps) {
tv_tab_title.setText(tv_tab_title.getText().toString().toUpperCase());
}
if (mTextBold == TEXT_BOLD_BOTH) {
tv_tab_title.getPaint().setFakeBoldText(true);
} else if (mTextBold == TEXT_BOLD_NONE) {
tv_tab_title.getPaint().setFakeBoldText(false);
}
}
}
private void updateTabSelection(int position) {
for (int i = 0; i < mTabCount; ++i) {
View tabView = mTabsContainer.getChildAt(i);
final boolean isSelect = i == position;
TextView tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
tab_title.setTextColor(isSelect ? mTextSelectColor : mTextUnselectColor);
if (mTextBold == TEXT_BOLD_WHEN_SELECT) {
tab_title.getPaint().setFakeBoldText(isSelect);
}
}
}
private void calcOffset() {
final View currentTabView = mTabsContainer.getChildAt(this.mCurrentTab);
mCurrentP.left = currentTabView.getLeft();
mCurrentP.right = currentTabView.getRight();
final View lastTabView = mTabsContainer.getChildAt(this.mLastTab);
mLastP.left = lastTabView.getLeft();
mLastP.right = lastTabView.getRight();
if (mLastP.left == mCurrentP.left && mLastP.right == mCurrentP.right) {
invalidate();
} else {
mValueAnimator.setObjectValues(mLastP, mCurrentP);
if (mIndicatorBounceEnable) {
mValueAnimator.setInterpolator(mInterpolator);
}
if (mIndicatorAnimDuration < 0) {
mIndicatorAnimDuration = mIndicatorBounceEnable ? 500 : 250;
}
mValueAnimator.setDuration(mIndicatorAnimDuration);
mValueAnimator.start();
}
}
private void calcIndicatorRect() {
View currentTabView = mTabsContainer.getChildAt(this.mCurrentTab);
float left = currentTabView.getLeft();
float right = currentTabView.getRight();
mIndicatorRect.left = (int) left;
mIndicatorRect.right = (int) right;
if (!mIndicatorAnimEnable) {
if (mCurrentTab == 0) {
/**The corners are ordered top-left, top-right, bottom-right, bottom-left*/
mRadiusArr[0] = mIndicatorCornerRadius;
mRadiusArr[1] = mIndicatorCornerRadius;
mRadiusArr[2] = 0;
mRadiusArr[3] = 0;
mRadiusArr[4] = 0;
mRadiusArr[5] = 0;
mRadiusArr[6] = mIndicatorCornerRadius;
mRadiusArr[7] = mIndicatorCornerRadius;
} else if (mCurrentTab == mTabCount - 1) {
/**The corners are ordered top-left, top-right, bottom-right, bottom-left*/
mRadiusArr[0] = 0;
mRadiusArr[1] = 0;
mRadiusArr[2] = mIndicatorCornerRadius;
mRadiusArr[3] = mIndicatorCornerRadius;
mRadiusArr[4] = mIndicatorCornerRadius;
mRadiusArr[5] = mIndicatorCornerRadius;
mRadiusArr[6] = 0;
mRadiusArr[7] = 0;
} else {
/**The corners are ordered top-left, top-right, bottom-right, bottom-left*/
mRadiusArr[0] = 0;
mRadiusArr[1] = 0;
mRadiusArr[2] = 0;
mRadiusArr[3] = 0;
mRadiusArr[4] = 0;
mRadiusArr[5] = 0;
mRadiusArr[6] = 0;
mRadiusArr[7] = 0;
}
} else {
/**The corners are ordered top-left, top-right, bottom-right, bottom-left*/
mRadiusArr[0] = mIndicatorCornerRadius;
mRadiusArr[1] = mIndicatorCornerRadius;
mRadiusArr[2] = mIndicatorCornerRadius;
mRadiusArr[3] = mIndicatorCornerRadius;
mRadiusArr[4] = mIndicatorCornerRadius;
mRadiusArr[5] = mIndicatorCornerRadius;
mRadiusArr[6] = mIndicatorCornerRadius;
mRadiusArr[7] = mIndicatorCornerRadius;
}
}
@Override
public void onAnimationUpdate(ValueAnimator animation) {
IndicatorPoint p = (IndicatorPoint) animation.getAnimatedValue();
mIndicatorRect.left = (int) p.left;
mIndicatorRect.right = (int) p.right;
invalidate();
}
private boolean mIsFirstDraw = true;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isInEditMode() || mTabCount <= 0) {
return;
}
int height = getHeight();
int paddingLeft = getPaddingLeft();
if (mIndicatorHeight < 0) {
mIndicatorHeight = height - mIndicatorMarginTop - mIndicatorMarginBottom;
}
if (mIndicatorCornerRadius < 0 || mIndicatorCornerRadius > mIndicatorHeight / 2) {
mIndicatorCornerRadius = mIndicatorHeight / 2;
}
//draw rect
mRectDrawable.setColor(mBarColor);
mRectDrawable.setStroke((int) mBarStrokeWidth, mBarStrokeColor);
mRectDrawable.setCornerRadius(mIndicatorCornerRadius);
mRectDrawable.setBounds(getPaddingLeft(), getPaddingTop(), getWidth() - getPaddingRight(), getHeight() - getPaddingBottom());
mRectDrawable.draw(canvas);
// draw divider
if (!mIndicatorAnimEnable && mDividerWidth > 0) {
mDividerPaint.setStrokeWidth(mDividerWidth);
mDividerPaint.setColor(mDividerColor);
for (int i = 0; i < mTabCount - 1; i++) {
View tab = mTabsContainer.getChildAt(i);
canvas.drawLine(paddingLeft + tab.getRight(), mDividerPadding, paddingLeft + tab.getRight(), height - mDividerPadding, mDividerPaint);
}
}
//draw indicator line
if (mIndicatorAnimEnable) {
if (mIsFirstDraw) {
mIsFirstDraw = false;
calcIndicatorRect();
}
} else {
calcIndicatorRect();
}
mIndicatorDrawable.setColor(mIndicatorColor);
mIndicatorDrawable.setBounds(paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,
(int) mIndicatorMarginTop, (int) (paddingLeft + mIndicatorRect.right - mIndicatorMarginRight),
(int) (mIndicatorMarginTop + mIndicatorHeight));
mIndicatorDrawable.setCornerRadii(mRadiusArr);
mIndicatorDrawable.draw(canvas);
}
//setter and getter
public void setCurrentTab(int currentTab) {
mLastTab = this.mCurrentTab;
this.mCurrentTab = currentTab;
updateTabSelection(currentTab);
if (mFragmentChangeManager != null) {
mFragmentChangeManager.setFragments(currentTab);
}
if (mIndicatorAnimEnable) {
calcOffset();
} else {
invalidate();
}
}
public void setTabPadding(float tabPadding) {
this.mTabPadding = DisplayUtil.dp2px(mContext, tabPadding);
updateTabStyles();
}
public void setTabSpaceEqual(boolean tabSpaceEqual) {
this.mTabSpaceEqual = tabSpaceEqual;
updateTabStyles();
}
public void setTabWidth(float tabWidth) {
this.mTabWidth = DisplayUtil.dp2px(mContext, tabWidth);
updateTabStyles();
}
public void setIndicatorColor(int indicatorColor) {
this.mIndicatorColor = indicatorColor;
invalidate();
}
public void setIndicatorHeight(float indicatorHeight) {
this.mIndicatorHeight = DisplayUtil.dp2px(mContext, indicatorHeight);
invalidate();
}
public void setIndicatorCornerRadius(float indicatorCornerRadius) {
this.mIndicatorCornerRadius = DisplayUtil.dp2px(mContext, indicatorCornerRadius);
invalidate();
}
public void setIndicatorMargin(float indicatorMarginLeft, float indicatorMarginTop,
float indicatorMarginRight, float indicatorMarginBottom) {
this.mIndicatorMarginLeft = DisplayUtil.dp2px(mContext, indicatorMarginLeft);
this.mIndicatorMarginTop = DisplayUtil.dp2px(mContext, indicatorMarginTop);
this.mIndicatorMarginRight = DisplayUtil.dp2px(mContext, indicatorMarginRight);
this.mIndicatorMarginBottom = DisplayUtil.dp2px(mContext, indicatorMarginBottom);
invalidate();
}
public void setIndicatorAnimDuration(long indicatorAnimDuration) {
this.mIndicatorAnimDuration = indicatorAnimDuration;
}
public void setIndicatorAnimEnable(boolean indicatorAnimEnable) {
this.mIndicatorAnimEnable = indicatorAnimEnable;
}
public void setIndicatorBounceEnable(boolean indicatorBounceEnable) {
this.mIndicatorBounceEnable = indicatorBounceEnable;
}
public void setDividerColor(int dividerColor) {
this.mDividerColor = dividerColor;
invalidate();
}
public void setDividerWidth(float dividerWidth) {
this.mDividerWidth = DisplayUtil.dp2px(mContext, dividerWidth);
invalidate();
}
public void setDividerPadding(float dividerPadding) {
this.mDividerPadding = DisplayUtil.dp2px(mContext, dividerPadding);
invalidate();
}
public void setTextsize(float textsize) {
this.mTextsize = DisplayUtil.sp2px(mContext, textsize);
updateTabStyles();
}
public void setTextSelectColor(int textSelectColor) {
this.mTextSelectColor = textSelectColor;
updateTabStyles();
}
public void setTextUnselectColor(int textUnselectColor) {
this.mTextUnselectColor = textUnselectColor;
updateTabStyles();
}
public void setTextBold(int textBold) {
this.mTextBold = textBold;
updateTabStyles();
}
public void setTextAllCaps(boolean textAllCaps) {
this.mTextAllCaps = textAllCaps;
updateTabStyles();
}
public int getTabCount() {
return mTabCount;
}
public int getCurrentTab() {
return mCurrentTab;
}
public float getTabPadding() {
return mTabPadding;
}
public boolean isTabSpaceEqual() {
return mTabSpaceEqual;
}
public float getTabWidth() {
return mTabWidth;
}
public int getIndicatorColor() {
return mIndicatorColor;
}
public float getIndicatorHeight() {
return mIndicatorHeight;
}
public float getIndicatorCornerRadius() {
return mIndicatorCornerRadius;
}
public float getIndicatorMarginLeft() {
return mIndicatorMarginLeft;
}
public float getIndicatorMarginTop() {
return mIndicatorMarginTop;
}
public float getIndicatorMarginRight() {
return mIndicatorMarginRight;
}
public float getIndicatorMarginBottom() {
return mIndicatorMarginBottom;
}
public long getIndicatorAnimDuration() {
return mIndicatorAnimDuration;
}
public boolean isIndicatorAnimEnable() {
return mIndicatorAnimEnable;
}
public boolean isIndicatorBounceEnable() {
return mIndicatorBounceEnable;
}
public int getDividerColor() {
return mDividerColor;
}
public float getDividerWidth() {
return mDividerWidth;
}
public float getDividerPadding() {
return mDividerPadding;
}
public float getTextsize() {
return mTextsize;
}
public int getTextSelectColor() {
return mTextSelectColor;
}
public int getTextUnselectColor() {
return mTextUnselectColor;
}
public int getTextBold() {
return mTextBold;
}
public boolean isTextAllCaps() {
return mTextAllCaps;
}
public TextView getTitleView(int tab) {
View tabView = mTabsContainer.getChildAt(tab);
TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
return tv_tab_title;
}
//setter and getter
// show MsgTipView
private Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private SparseArray<Boolean> mInitSetMap = new SparseArray<>();
public void showMsg(int position, int num) {
if (position >= mTabCount) {
position = mTabCount - 1;
}
View tabView = mTabsContainer.getChildAt(position);
MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);
if (tipView != null) {
UnreadMsgUtils.show(tipView, num);
if (mInitSetMap.get(position) != null && mInitSetMap.get(position)) {
return;
}
setMsgMargin(position, 2, 2);
mInitSetMap.put(position, true);
}
}
public void showDot(int position) {
if (position >= mTabCount) {
position = mTabCount - 1;
}
showMsg(position, 0);
}
public void hideMsg(int position) {
if (position >= mTabCount) {
position = mTabCount - 1;
}
View tabView = mTabsContainer.getChildAt(position);
MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);
if (tipView != null) {
tipView.setVisibility(View.GONE);
}
}
public void setMsgMargin(int position, float leftPadding, float bottomPadding) {
if (position >= mTabCount) {
position = mTabCount - 1;
}
View tabView = mTabsContainer.getChildAt(position);
MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);
if (tipView != null) {
TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
mTextPaint.setTextSize(mTextsize);
float textWidth = mTextPaint.measureText(tv_tab_title.getText().toString());
float textHeight = mTextPaint.descent() - mTextPaint.ascent();
MarginLayoutParams lp = (MarginLayoutParams) tipView.getLayoutParams();
lp.leftMargin = DisplayUtil.dp2px(mContext, leftPadding);
lp.topMargin = mHeight > 0 ? (int) (mHeight - textHeight) / 2 - DisplayUtil.dp2px(mContext, bottomPadding) : DisplayUtil.dp2px(mContext, bottomPadding);
tipView.setLayoutParams(lp);
}
}
public MsgView getMsgView(int position) {
if (position >= mTabCount) {
position = mTabCount - 1;
}
View tabView = mTabsContainer.getChildAt(position);
MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);
return tipView;
}
private OnTabSelectListener mListener;
public void setOnTabSelectListener(OnTabSelectListener listener) {
this.mListener = listener;
}
@Override
protected Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
bundle.putParcelable("instanceState", super.onSaveInstanceState());
bundle.putInt("mCurrentTab", mCurrentTab);
return bundle;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
Bundle bundle = (Bundle) state;
mCurrentTab = bundle.getInt("mCurrentTab");
state = bundle.getParcelable("instanceState");
if (mCurrentTab != 0 && mTabsContainer.getChildCount() > 0) {
updateTabSelection(mCurrentTab);
}
}
super.onRestoreInstanceState(state);
}
class IndicatorPoint {
public float left;
public float right;
}
private IndicatorPoint mCurrentP = new IndicatorPoint();
private IndicatorPoint mLastP = new IndicatorPoint();
class PointEvaluator implements TypeEvaluator<IndicatorPoint> {
@Override
public IndicatorPoint evaluate(float fraction, IndicatorPoint startValue, IndicatorPoint endValue) {
float left = startValue.left + fraction * (endValue.left - startValue.left);
float right = startValue.right + fraction * (endValue.right - startValue.right);
IndicatorPoint point = new IndicatorPoint();
point.left = left;
point.right = right;
return point;
}
}
}

View File

@ -1,907 +0,0 @@
/**
* Copyright 2021 Huawei Technologies Co., Ltd
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mindspore.customview.tablayout;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.mindspore.common.utils.DisplayUtil;
import com.mindspore.customview.R;
import com.mindspore.customview.tablayout.listener.OnTabSelectListener;
import com.mindspore.customview.tablayout.utils.UnreadMsgUtils;
import com.mindspore.customview.tablayout.widget.MsgView;
import java.util.ArrayList;
import java.util.Collections;
public class SlidingTabLayout extends HorizontalScrollView implements ViewPager.OnPageChangeListener {
private Context mContext;
private ViewPager mViewPager;
private ArrayList<String> mTitles;
private LinearLayout mTabsContainer;
private int mCurrentTab;
private float mCurrentPositionOffset;
private int mTabCount;
private Rect mIndicatorRect = new Rect();
private Rect mTabRect = new Rect();
private GradientDrawable mIndicatorDrawable = new GradientDrawable();
private Paint mRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint mDividerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint mTrianglePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Path mTrianglePath = new Path();
private static final int STYLE_NORMAL = 0;
private static final int STYLE_TRIANGLE = 1;
private static final int STYLE_BLOCK = 2;
private int mIndicatorStyle = STYLE_NORMAL;
private float mTabPadding;
private boolean mTabSpaceEqual;
private float mTabWidth;
/**
* indicator
*/
private int mIndicatorColor;
private float mIndicatorHeight;
private float mIndicatorWidth;
private float mIndicatorCornerRadius;
private float mIndicatorMarginLeft;
private float mIndicatorMarginTop;
private float mIndicatorMarginRight;
private float mIndicatorMarginBottom;
private int mIndicatorGravity;
private boolean mIndicatorWidthEqualTitle;
/**
* underline
*/
private int mUnderlineColor;
private float mUnderlineHeight;
private int mUnderlineGravity;
/**
* divider
*/
private int mDividerColor;
private float mDividerWidth;
private float mDividerPadding;
/**
* title
*/
private static final int TEXT_BOLD_NONE = 0;
private static final int TEXT_BOLD_WHEN_SELECT = 1;
private static final int TEXT_BOLD_BOTH = 2;
private float mTextsize;
private int mTextSelectColor;
private int mTextUnselectColor;
private int mTextBold;
private boolean mTextAllCaps;
private int mLastScrollX;
private int mHeight;
private boolean mSnapOnTabClick;
public SlidingTabLayout(Context context) {
this(context, null, 0);
}
public SlidingTabLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SlidingTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setFillViewport(true);
setWillNotDraw(false);
setClipChildren(false);
setClipToPadding(false);
this.mContext = context;
mTabsContainer = new LinearLayout(context);
addView(mTabsContainer);
obtainAttributes(context, attrs);
//get layout_height
String height = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "layout_height");
if (height.equals(ViewGroup.LayoutParams.MATCH_PARENT + "")) {
} else if (height.equals(ViewGroup.LayoutParams.WRAP_CONTENT + "")) {
} else {
int[] systemAttrs = {android.R.attr.layout_height};
TypedArray a = context.obtainStyledAttributes(attrs, systemAttrs);
mHeight = a.getDimensionPixelSize(0, ViewGroup.LayoutParams.WRAP_CONTENT);
a.recycle();
}
}
private void obtainAttributes(Context context, AttributeSet attrs) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SlidingTabLayout);
mIndicatorStyle = ta.getInt(R.styleable.SlidingTabLayout_tl_indicator_style, STYLE_NORMAL);
mIndicatorColor = ta.getColor(R.styleable.SlidingTabLayout_tl_indicator_color, Color.parseColor(mIndicatorStyle == STYLE_BLOCK ? "#4B6A87" : "#ffffff"));
mIndicatorHeight = ta.getDimension(R.styleable.SlidingTabLayout_tl_indicator_height,
DisplayUtil.dp2px(context, mIndicatorStyle == STYLE_TRIANGLE ? 4 : (mIndicatorStyle == STYLE_BLOCK ? -1 : 2)));
mIndicatorWidth = ta.getDimension(R.styleable.SlidingTabLayout_tl_indicator_width, DisplayUtil.dp2px(context, mIndicatorStyle == STYLE_TRIANGLE ? 10 : -1));
mIndicatorCornerRadius = ta.getDimension(R.styleable.SlidingTabLayout_tl_indicator_corner_radius, DisplayUtil.dp2px(context, mIndicatorStyle == STYLE_BLOCK ? -1 : 0));
mIndicatorMarginLeft = ta.getDimension(R.styleable.SlidingTabLayout_tl_indicator_margin_left, DisplayUtil.dp2px(context, 0));
mIndicatorMarginTop = ta.getDimension(R.styleable.SlidingTabLayout_tl_indicator_margin_top, DisplayUtil.dp2px(context, mIndicatorStyle == STYLE_BLOCK ? 7 : 0));
mIndicatorMarginRight = ta.getDimension(R.styleable.SlidingTabLayout_tl_indicator_margin_right, DisplayUtil.dp2px(context, 0));
mIndicatorMarginBottom = ta.getDimension(R.styleable.SlidingTabLayout_tl_indicator_margin_bottom, DisplayUtil.dp2px(context, mIndicatorStyle == STYLE_BLOCK ? 7 : 0));
mIndicatorGravity = ta.getInt(R.styleable.SlidingTabLayout_tl_indicator_gravity, Gravity.BOTTOM);
mIndicatorWidthEqualTitle = ta.getBoolean(R.styleable.SlidingTabLayout_tl_indicator_width_equal_title, false);
mUnderlineColor = ta.getColor(R.styleable.SlidingTabLayout_tl_underline_color, Color.parseColor("#ffffff"));
mUnderlineHeight = ta.getDimension(R.styleable.SlidingTabLayout_tl_underline_height, DisplayUtil.dp2px(context, 0));
mUnderlineGravity = ta.getInt(R.styleable.SlidingTabLayout_tl_underline_gravity, Gravity.BOTTOM);
mDividerColor = ta.getColor(R.styleable.SlidingTabLayout_tl_divider_color, Color.parseColor("#ffffff"));
mDividerWidth = ta.getDimension(R.styleable.SlidingTabLayout_tl_divider_width, DisplayUtil.dp2px(context, 0));
mDividerPadding = ta.getDimension(R.styleable.SlidingTabLayout_tl_divider_padding, DisplayUtil.dp2px(context, 12));
mTextsize = ta.getDimension(R.styleable.SlidingTabLayout_tl_textsize, DisplayUtil.sp2px(context, 14));
mTextSelectColor = ta.getColor(R.styleable.SlidingTabLayout_tl_textSelectColor, Color.parseColor("#ffffff"));
mTextUnselectColor = ta.getColor(R.styleable.SlidingTabLayout_tl_textUnselectColor, Color.parseColor("#AAffffff"));
mTextBold = ta.getInt(R.styleable.SlidingTabLayout_tl_textBold, TEXT_BOLD_NONE);
mTextAllCaps = ta.getBoolean(R.styleable.SlidingTabLayout_tl_textAllCaps, false);
mTabSpaceEqual = ta.getBoolean(R.styleable.SlidingTabLayout_tl_tab_space_equal, false);
mTabWidth = ta.getDimension(R.styleable.SlidingTabLayout_tl_tab_width, DisplayUtil.dp2px(context, -1));
mTabPadding = ta.getDimension(R.styleable.SlidingTabLayout_tl_tab_padding, mTabSpaceEqual || mTabWidth > 0 ? DisplayUtil.dp2px(context, 0) : DisplayUtil.dp2px(context, 20));
ta.recycle();
}
public void setViewPager(ViewPager vp) {
if (vp == null || vp.getAdapter() == null) {
throw new IllegalStateException("ViewPager or ViewPager adapter can not be NULL !");
}
this.mViewPager = vp;
this.mViewPager.removeOnPageChangeListener(this);
this.mViewPager.addOnPageChangeListener(this);
notifyDataSetChanged();
}
public void setViewPager(ViewPager vp, String[] titles) {
if (vp == null || vp.getAdapter() == null) {
throw new IllegalStateException("ViewPager or ViewPager adapter can not be NULL !");
}
if (titles == null || titles.length == 0) {
throw new IllegalStateException("Titles can not be EMPTY !");
}
if (titles.length != vp.getAdapter().getCount()) {
throw new IllegalStateException("Titles length must be the same as the page count !");
}
this.mViewPager = vp;
mTitles = new ArrayList<>();
Collections.addAll(mTitles, titles);
this.mViewPager.removeOnPageChangeListener(this);
this.mViewPager.addOnPageChangeListener(this);
notifyDataSetChanged();
}
public void setViewPager(ViewPager vp, String[] titles, FragmentActivity fa, ArrayList<Fragment> fragments) {
if (vp == null) {
throw new IllegalStateException("ViewPager can not be NULL !");
}
if (titles == null || titles.length == 0) {
throw new IllegalStateException("Titles can not be EMPTY !");
}
this.mViewPager = vp;
this.mViewPager.setAdapter(new InnerPagerAdapter(fa.getSupportFragmentManager(), fragments, titles));
this.mViewPager.removeOnPageChangeListener(this);
this.mViewPager.addOnPageChangeListener(this);
notifyDataSetChanged();
}
public void notifyDataSetChanged() {
mTabsContainer.removeAllViews();
this.mTabCount = mTitles == null ? mViewPager.getAdapter().getCount() : mTitles.size();
View tabView;
for (int i = 0; i < mTabCount; i++) {
tabView = View.inflate(mContext, R.layout.layout_tab, null);
CharSequence pageTitle = mTitles == null ? mViewPager.getAdapter().getPageTitle(i) : mTitles.get(i);
addTab(i, pageTitle.toString(), tabView);
}
updateTabStyles();
}
public void addNewTab(String title) {
View tabView = View.inflate(mContext, R.layout.layout_tab, null);
if (mTitles != null) {
mTitles.add(title);
}
CharSequence pageTitle = mTitles == null ? mViewPager.getAdapter().getPageTitle(mTabCount) : mTitles.get(mTabCount);
addTab(mTabCount, pageTitle.toString(), tabView);
this.mTabCount = mTitles == null ? mViewPager.getAdapter().getCount() : mTitles.size();
updateTabStyles();
}
private void addTab(final int position, String title, View tabView) {
TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
if (tv_tab_title != null) {
if (title != null) tv_tab_title.setText(title);
}
tabView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int position = mTabsContainer.indexOfChild(v);
if (position != -1) {
if (mViewPager.getCurrentItem() != position) {
if (mSnapOnTabClick) {
mViewPager.setCurrentItem(position, false);
} else {
mViewPager.setCurrentItem(position);
}
if (mListener != null) {
mListener.onTabSelect(position);
}
} else {
if (mListener != null) {
mListener.onTabReselect(position);
}
}
}
}
});
LinearLayout.LayoutParams lp_tab = mTabSpaceEqual ?
new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f) :
new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
if (mTabWidth > 0) {
lp_tab = new LinearLayout.LayoutParams((int) mTabWidth, LayoutParams.MATCH_PARENT);
}
mTabsContainer.addView(tabView, position, lp_tab);
}
private void updateTabStyles() {
for (int i = 0; i < mTabCount; i++) {
View v = mTabsContainer.getChildAt(i);
// v.setPadding((int) mTabPadding, v.getPaddingTop(), (int) mTabPadding, v.getPaddingBottom());
TextView tv_tab_title = (TextView) v.findViewById(R.id.tv_tab_title);
if (tv_tab_title != null) {
tv_tab_title.setTextColor(i == mCurrentTab ? mTextSelectColor : mTextUnselectColor);
tv_tab_title.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextsize);
tv_tab_title.setPadding((int) mTabPadding, 0, (int) mTabPadding, 0);
if (mTextAllCaps) {
tv_tab_title.setText(tv_tab_title.getText().toString().toUpperCase());
}
if (mTextBold == TEXT_BOLD_BOTH) {
tv_tab_title.getPaint().setFakeBoldText(true);
} else if (mTextBold == TEXT_BOLD_NONE) {
tv_tab_title.getPaint().setFakeBoldText(false);
}
}
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
this.mCurrentTab = position;
this.mCurrentPositionOffset = positionOffset;
scrollToCurrentTab();
invalidate();
}
@Override
public void onPageSelected(int position) {
updateTabSelection(position);
}
@Override
public void onPageScrollStateChanged(int state) {
}
/**
* HorizontalScrollView滚到当前tab,并且居中显示
*/
private void scrollToCurrentTab() {
if (mTabCount <= 0) {
return;
}
int offset = (int) (mCurrentPositionOffset * mTabsContainer.getChildAt(mCurrentTab).getWidth());
int newScrollX = mTabsContainer.getChildAt(mCurrentTab).getLeft() + offset;
if (mCurrentTab > 0 || offset > 0) {
/**HorizontalScrollView移动到当前tab,并居中*/
newScrollX -= getWidth() / 2 - getPaddingLeft();
calcIndicatorRect();
newScrollX += ((mTabRect.right - mTabRect.left) / 2);
}
if (newScrollX != mLastScrollX) {
mLastScrollX = newScrollX;
scrollTo(newScrollX, 0);
}
}
private void updateTabSelection(int position) {
for (int i = 0; i < mTabCount; ++i) {
View tabView = mTabsContainer.getChildAt(i);
final boolean isSelect = i == position;
TextView tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
if (tab_title != null) {
tab_title.setTextColor(isSelect ? mTextSelectColor : mTextUnselectColor);
if (mTextBold == TEXT_BOLD_WHEN_SELECT) {
tab_title.getPaint().setFakeBoldText(isSelect);
}
}
}
}
private float margin;
private void calcIndicatorRect() {
View currentTabView = mTabsContainer.getChildAt(this.mCurrentTab);
float left = currentTabView.getLeft();
float right = currentTabView.getRight();
//for mIndicatorWidthEqualTitle
if (mIndicatorStyle == STYLE_NORMAL && mIndicatorWidthEqualTitle) {
TextView tab_title = (TextView) currentTabView.findViewById(R.id.tv_tab_title);
mTextPaint.setTextSize(mTextsize);
float textWidth = mTextPaint.measureText(tab_title.getText().toString());
margin = (right - left - textWidth) / 2;
}
if (this.mCurrentTab < mTabCount - 1) {
View nextTabView = mTabsContainer.getChildAt(this.mCurrentTab + 1);
float nextTabLeft = nextTabView.getLeft();
float nextTabRight = nextTabView.getRight();
left = left + mCurrentPositionOffset * (nextTabLeft - left);
right = right + mCurrentPositionOffset * (nextTabRight - right);
//for mIndicatorWidthEqualTitle
if (mIndicatorStyle == STYLE_NORMAL && mIndicatorWidthEqualTitle) {
TextView next_tab_title = (TextView) nextTabView.findViewById(R.id.tv_tab_title);
mTextPaint.setTextSize(mTextsize);
float nextTextWidth = mTextPaint.measureText(next_tab_title.getText().toString());
float nextMargin = (nextTabRight - nextTabLeft - nextTextWidth) / 2;
margin = margin + mCurrentPositionOffset * (nextMargin - margin);
}
}
mIndicatorRect.left = (int) left;
mIndicatorRect.right = (int) right;
//for mIndicatorWidthEqualTitle
if (mIndicatorStyle == STYLE_NORMAL && mIndicatorWidthEqualTitle) {
mIndicatorRect.left = (int) (left + margin - 1);
mIndicatorRect.right = (int) (right - margin - 1);
}
mTabRect.left = (int) left;
mTabRect.right = (int) right;
if (mIndicatorWidth < 0) {
} else {
float indicatorLeft = currentTabView.getLeft() + (currentTabView.getWidth() - mIndicatorWidth) / 2;
if (this.mCurrentTab < mTabCount - 1) {
View nextTab = mTabsContainer.getChildAt(this.mCurrentTab + 1);
indicatorLeft = indicatorLeft + mCurrentPositionOffset * (currentTabView.getWidth() / 2 + nextTab.getWidth() / 2);
}
mIndicatorRect.left = (int) indicatorLeft;
mIndicatorRect.right = (int) (mIndicatorRect.left + mIndicatorWidth);
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isInEditMode() || mTabCount <= 0) {
return;
}
int height = getHeight();
int paddingLeft = getPaddingLeft();
// draw divider
if (mDividerWidth > 0) {
mDividerPaint.setStrokeWidth(mDividerWidth);
mDividerPaint.setColor(mDividerColor);
for (int i = 0; i < mTabCount - 1; i++) {
View tab = mTabsContainer.getChildAt(i);
canvas.drawLine(paddingLeft + tab.getRight(), mDividerPadding, paddingLeft + tab.getRight(), height - mDividerPadding, mDividerPaint);
}
}
// draw underline
if (mUnderlineHeight > 0) {
mRectPaint.setColor(mUnderlineColor);
if (mUnderlineGravity == Gravity.BOTTOM) {
canvas.drawRect(paddingLeft, height - mUnderlineHeight, mTabsContainer.getWidth() + paddingLeft, height, mRectPaint);
} else {
canvas.drawRect(paddingLeft, 0, mTabsContainer.getWidth() + paddingLeft, mUnderlineHeight, mRectPaint);
}
}
//draw indicator line
calcIndicatorRect();
if (mIndicatorStyle == STYLE_TRIANGLE) {
if (mIndicatorHeight > 0) {
mTrianglePaint.setColor(mIndicatorColor);
mTrianglePath.reset();
mTrianglePath.moveTo(paddingLeft + mIndicatorRect.left, height);
mTrianglePath.lineTo(paddingLeft + mIndicatorRect.left / 2 + mIndicatorRect.right / 2, height - mIndicatorHeight);
mTrianglePath.lineTo(paddingLeft + mIndicatorRect.right, height);
mTrianglePath.close();
canvas.drawPath(mTrianglePath, mTrianglePaint);
}
} else if (mIndicatorStyle == STYLE_BLOCK) {
if (mIndicatorHeight < 0) {
mIndicatorHeight = height - mIndicatorMarginTop - mIndicatorMarginBottom;
} else {
}
if (mIndicatorHeight > 0) {
if (mIndicatorCornerRadius < 0 || mIndicatorCornerRadius > mIndicatorHeight / 2) {
mIndicatorCornerRadius = mIndicatorHeight / 2;
}
mIndicatorDrawable.setColor(mIndicatorColor);
mIndicatorDrawable.setBounds(paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,
(int) mIndicatorMarginTop, (int) (paddingLeft + mIndicatorRect.right - mIndicatorMarginRight),
(int) (mIndicatorMarginTop + mIndicatorHeight));
mIndicatorDrawable.setCornerRadius(mIndicatorCornerRadius);
mIndicatorDrawable.draw(canvas);
}
} else {
/* mRectPaint.setColor(mIndicatorColor);
calcIndicatorRect();
canvas.drawRect(getPaddingLeft() + mIndicatorRect.left, getHeight() - mIndicatorHeight,
mIndicatorRect.right + getPaddingLeft(), getHeight(), mRectPaint);*/
if (mIndicatorHeight > 0) {
mIndicatorDrawable.setColor(mIndicatorColor);
if (mIndicatorGravity == Gravity.BOTTOM) {
mIndicatorDrawable.setBounds(paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,
height - (int) mIndicatorHeight - (int) mIndicatorMarginBottom,
paddingLeft + mIndicatorRect.right - (int) mIndicatorMarginRight,
height - (int) mIndicatorMarginBottom);
} else {
mIndicatorDrawable.setBounds(paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,
(int) mIndicatorMarginTop,
paddingLeft + mIndicatorRect.right - (int) mIndicatorMarginRight,
(int) mIndicatorHeight + (int) mIndicatorMarginTop);
}
mIndicatorDrawable.setCornerRadius(mIndicatorCornerRadius);
mIndicatorDrawable.draw(canvas);
}
}
}
//setter and getter
public void setCurrentTab(int currentTab) {
this.mCurrentTab = currentTab;
mViewPager.setCurrentItem(currentTab);
}
public void setCurrentTab(int currentTab, boolean smoothScroll) {
this.mCurrentTab = currentTab;
mViewPager.setCurrentItem(currentTab, smoothScroll);
}
public void setIndicatorStyle(int indicatorStyle) {
this.mIndicatorStyle = indicatorStyle;
invalidate();
}
public void setTabPadding(float tabPadding) {
this.mTabPadding = DisplayUtil.dp2px(mContext, tabPadding);
updateTabStyles();
}
public void setTabSpaceEqual(boolean tabSpaceEqual) {
this.mTabSpaceEqual = tabSpaceEqual;
updateTabStyles();
}
public void setTabWidth(float tabWidth) {
this.mTabWidth = DisplayUtil.dp2px(mContext, tabWidth);
updateTabStyles();
}
public void setIndicatorColor(int indicatorColor) {
this.mIndicatorColor = indicatorColor;
invalidate();
}
public void setIndicatorHeight(float indicatorHeight) {
this.mIndicatorHeight = DisplayUtil.dp2px(mContext, indicatorHeight);
invalidate();
}
public void setIndicatorWidth(float indicatorWidth) {
this.mIndicatorWidth = DisplayUtil.dp2px(mContext, indicatorWidth);
invalidate();
}
public void setIndicatorCornerRadius(float indicatorCornerRadius) {
this.mIndicatorCornerRadius = DisplayUtil.dp2px(mContext, indicatorCornerRadius);
invalidate();
}
public void setIndicatorGravity(int indicatorGravity) {
this.mIndicatorGravity = indicatorGravity;
invalidate();
}
public void setIndicatorMargin(float indicatorMarginLeft, float indicatorMarginTop,
float indicatorMarginRight, float indicatorMarginBottom) {
this.mIndicatorMarginLeft = DisplayUtil.dp2px(mContext, indicatorMarginLeft);
this.mIndicatorMarginTop = DisplayUtil.dp2px(mContext, indicatorMarginTop);
this.mIndicatorMarginRight = DisplayUtil.dp2px(mContext, indicatorMarginRight);
this.mIndicatorMarginBottom = DisplayUtil.dp2px(mContext, indicatorMarginBottom);
invalidate();
}
public void setIndicatorWidthEqualTitle(boolean indicatorWidthEqualTitle) {
this.mIndicatorWidthEqualTitle = indicatorWidthEqualTitle;
invalidate();
}
public void setUnderlineColor(int underlineColor) {
this.mUnderlineColor = underlineColor;
invalidate();
}
public void setUnderlineHeight(float underlineHeight) {
this.mUnderlineHeight = DisplayUtil.dp2px(mContext, underlineHeight);
invalidate();
}
public void setUnderlineGravity(int underlineGravity) {
this.mUnderlineGravity = underlineGravity;
invalidate();
}
public void setDividerColor(int dividerColor) {
this.mDividerColor = dividerColor;
invalidate();
}
public void setDividerWidth(float dividerWidth) {
this.mDividerWidth = DisplayUtil.dp2px(mContext, dividerWidth);
invalidate();
}
public void setDividerPadding(float dividerPadding) {
this.mDividerPadding = DisplayUtil.dp2px(mContext, dividerPadding);
invalidate();
}
public void setTextsize(float textsize) {
this.mTextsize = DisplayUtil.sp2px(mContext, textsize);
updateTabStyles();
}
public void setTextSelectColor(int textSelectColor) {
this.mTextSelectColor = textSelectColor;
updateTabStyles();
}
public void setTextUnselectColor(int textUnselectColor) {
this.mTextUnselectColor = textUnselectColor;
updateTabStyles();
}
public void setTextBold(int textBold) {
this.mTextBold = textBold;
updateTabStyles();
}
public void setTextAllCaps(boolean textAllCaps) {
this.mTextAllCaps = textAllCaps;
updateTabStyles();
}
public void setSnapOnTabClick(boolean snapOnTabClick) {
mSnapOnTabClick = snapOnTabClick;
}
public int getTabCount() {
return mTabCount;
}
public int getCurrentTab() {
return mCurrentTab;
}
public int getIndicatorStyle() {
return mIndicatorStyle;
}
public float getTabPadding() {
return mTabPadding;
}
public boolean isTabSpaceEqual() {
return mTabSpaceEqual;
}
public float getTabWidth() {
return mTabWidth;
}
public int getIndicatorColor() {
return mIndicatorColor;
}
public float getIndicatorHeight() {
return mIndicatorHeight;
}
public float getIndicatorWidth() {
return mIndicatorWidth;
}
public float getIndicatorCornerRadius() {
return mIndicatorCornerRadius;
}
public float getIndicatorMarginLeft() {
return mIndicatorMarginLeft;
}
public float getIndicatorMarginTop() {
return mIndicatorMarginTop;
}
public float getIndicatorMarginRight() {
return mIndicatorMarginRight;
}
public float getIndicatorMarginBottom() {
return mIndicatorMarginBottom;
}
public int getUnderlineColor() {
return mUnderlineColor;
}
public float getUnderlineHeight() {
return mUnderlineHeight;
}
public int getDividerColor() {
return mDividerColor;
}
public float getDividerWidth() {
return mDividerWidth;
}
public float getDividerPadding() {
return mDividerPadding;
}
public float getTextsize() {
return mTextsize;
}
public int getTextSelectColor() {
return mTextSelectColor;
}
public int getTextUnselectColor() {
return mTextUnselectColor;
}
public int getTextBold() {
return mTextBold;
}
public boolean isTextAllCaps() {
return mTextAllCaps;
}
public TextView getTitleView(int tab) {
View tabView = mTabsContainer.getChildAt(tab);
TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
return tv_tab_title;
}
//setter and getter
// show MsgTipView
private Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private SparseArray<Boolean> mInitSetMap = new SparseArray<>();
public void showMsg(int position, int num) {
if (position >= mTabCount) {
position = mTabCount - 1;
}
View tabView = mTabsContainer.getChildAt(position);
MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);
if (tipView != null) {
UnreadMsgUtils.show(tipView, num);
if (mInitSetMap.get(position) != null && mInitSetMap.get(position)) {
return;
}
setMsgMargin(position, 4, 2);
mInitSetMap.put(position, true);
}
}
public void showDot(int position) {
if (position >= mTabCount) {
position = mTabCount - 1;
}
showMsg(position, 0);
}
public void hideMsg(int position) {
if (position >= mTabCount) {
position = mTabCount - 1;
}
View tabView = mTabsContainer.getChildAt(position);
MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);
if (tipView != null) {
tipView.setVisibility(View.GONE);
}
}
public void setMsgMargin(int position, float leftPadding, float bottomPadding) {
if (position >= mTabCount) {
position = mTabCount - 1;
}
View tabView = mTabsContainer.getChildAt(position);
MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);
if (tipView != null) {
TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
mTextPaint.setTextSize(mTextsize);
float textWidth = mTextPaint.measureText(tv_tab_title.getText().toString());
float textHeight = mTextPaint.descent() - mTextPaint.ascent();
MarginLayoutParams lp = (MarginLayoutParams) tipView.getLayoutParams();
lp.leftMargin = mTabWidth >= 0 ? (int) (mTabWidth / 2 + textWidth / 2 + DisplayUtil.dp2px(mContext, leftPadding)) : (int) (mTabPadding + textWidth + DisplayUtil.dp2px(mContext, leftPadding));
lp.topMargin = mHeight > 0 ? (int) (mHeight - textHeight) / 2 - DisplayUtil.dp2px(mContext, bottomPadding) : 0;
tipView.setLayoutParams(lp);
}
}
public MsgView getMsgView(int position) {
if (position >= mTabCount) {
position = mTabCount - 1;
}
View tabView = mTabsContainer.getChildAt(position);
MsgView tipView = (MsgView) tabView.findViewById(R.id.rtv_msg_tip);
return tipView;
}
private OnTabSelectListener mListener;
public void setOnTabSelectListener(OnTabSelectListener listener) {
this.mListener = listener;
}
class InnerPagerAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> fragments = new ArrayList<>();
private String[] titles;
public InnerPagerAdapter(FragmentManager fm, ArrayList<Fragment> fragments, String[] titles) {
super(fm);
this.fragments = fragments;
this.titles = titles;
}
@Override
public int getCount() {
return fragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// 覆写destroyItem并且空实现,这样每个Fragment中的视图就不会被销毁
// super.destroyItem(container, position, object);
}
@Override
public int getItemPosition(Object object) {
return PagerAdapter.POSITION_NONE;
}
}
@Override
protected Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
bundle.putParcelable("instanceState", super.onSaveInstanceState());
bundle.putInt("mCurrentTab", mCurrentTab);
return bundle;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
Bundle bundle = (Bundle) state;
mCurrentTab = bundle.getInt("mCurrentTab");
state = bundle.getParcelable("instanceState");
if (mCurrentTab != 0 && mTabsContainer.getChildCount() > 0) {
updateTabSelection(mCurrentTab);
scrollToCurrentTab();
}
}
super.onRestoreInstanceState(state);
}
}

View File

@ -1,21 +0,0 @@
/**
* Copyright 2021 Huawei Technologies Co., Ltd
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mindspore.customview.tablayout.listener;
public interface OnTabSelectListener {
void onTabSelect(int position);
void onTabReselect(int position);
}

View File

@ -1,69 +0,0 @@
/**
* Copyright 2021 Huawei Technologies Co., Ltd
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mindspore.customview.tablayout.utils;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import java.util.ArrayList;
public class FragmentChangeManager {
private FragmentManager mFragmentManager;
private int mContainerViewId;
private ArrayList<Fragment> mFragments;
private int mCurrentTab;
public FragmentChangeManager(FragmentManager fm, int containerViewId, ArrayList<Fragment> fragments) {
this.mFragmentManager = fm;
this.mContainerViewId = containerViewId;
this.mFragments = fragments;
initFragments();
}
private void initFragments() {
for (Fragment fragment : mFragments) {
mFragmentManager.beginTransaction().add(mContainerViewId, fragment).hide(fragment).commit();
}
setFragments(0);
}
public void setFragments(int index) {
for (int i = 0; i < mFragments.size(); i++) {
FragmentTransaction ft = mFragmentManager.beginTransaction();
Fragment fragment = mFragments.get(i);
if (i == index) {
ft.show(fragment);
} else {
ft.hide(fragment);
}
ft.commit();
}
mCurrentTab = index;
}
public int getCurrentTab() {
return mCurrentTab;
}
public Fragment getCurrentFragment() {
return mFragments.get(mCurrentTab);
}
}

View File

@ -1,66 +0,0 @@
/**
* Copyright 2021 Huawei Technologies Co., Ltd
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mindspore.customview.tablayout.utils;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.RelativeLayout;
import com.mindspore.customview.tablayout.widget.MsgView;
public class UnreadMsgUtils {
public static void show(MsgView msgView, int num) {
if (msgView == null) {
return;
}
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) msgView.getLayoutParams();
DisplayMetrics dm = msgView.getResources().getDisplayMetrics();
msgView.setVisibility(View.VISIBLE);
if (num <= 0) {//圆点,设置默认宽高
msgView.setStrokeWidth(0);
msgView.setText("");
lp.width = (int) (5 * dm.density);
lp.height = (int) (5 * dm.density);
msgView.setLayoutParams(lp);
} else {
lp.height = (int) (18 * dm.density);
if (num > 0 && num < 10) {
lp.width = (int) (18 * dm.density);
msgView.setText(num + "");
} else if (num > 9 && num < 100) {
lp.width = RelativeLayout.LayoutParams.WRAP_CONTENT;
msgView.setPadding((int) (6 * dm.density), 0, (int) (6 * dm.density), 0);
msgView.setText(num + "");
} else {
lp.width = RelativeLayout.LayoutParams.WRAP_CONTENT;
msgView.setPadding((int) (6 * dm.density), 0, (int) (6 * dm.density), 0);
msgView.setText("99+");
}
msgView.setLayoutParams(lp);
}
}
public static void setSize(MsgView rtv, int size) {
if (rtv == null) {
return;
}
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) rtv.getLayoutParams();
lp.width = size;
lp.height = size;
rtv.setLayoutParams(lp);
}
}

View File

@ -1,150 +0,0 @@
package com.mindspore.customview.tablayout.widget;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.StateListDrawable;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.TextView;
import com.mindspore.common.utils.DisplayUtil;
import com.mindspore.customview.R;
@SuppressLint("AppCompatCustomView")
public class MsgView extends TextView {
private Context context;
private GradientDrawable gd_background = new GradientDrawable();
private int backgroundColor;
private int cornerRadius;
private int strokeWidth;
private int strokeColor;
private boolean isRadiusHalfHeight;
private boolean isWidthHeightEqual;
public MsgView(Context context) {
this(context, null);
}
public MsgView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MsgView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
obtainAttributes(context, attrs);
}
private void obtainAttributes(Context context, AttributeSet attrs) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MsgView);
backgroundColor = ta.getColor(R.styleable.MsgView_mv_backgroundColor, Color.TRANSPARENT);
cornerRadius = ta.getDimensionPixelSize(R.styleable.MsgView_mv_cornerRadius, 0);
strokeWidth = ta.getDimensionPixelSize(R.styleable.MsgView_mv_strokeWidth, 0);
strokeColor = ta.getColor(R.styleable.MsgView_mv_strokeColor, Color.TRANSPARENT);
isRadiusHalfHeight = ta.getBoolean(R.styleable.MsgView_mv_isRadiusHalfHeight, false);
isWidthHeightEqual = ta.getBoolean(R.styleable.MsgView_mv_isWidthHeightEqual, false);
ta.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (isWidthHeightEqual() && getWidth() > 0 && getHeight() > 0) {
int max = Math.max(getWidth(), getHeight());
int measureSpec = MeasureSpec.makeMeasureSpec(max, MeasureSpec.EXACTLY);
super.onMeasure(measureSpec, measureSpec);
return;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (isRadiusHalfHeight()) {
setCornerRadius(getHeight() / 2);
} else {
setBgSelector();
}
}
public void setBackgroundColor(int backgroundColor) {
this.backgroundColor = backgroundColor;
setBgSelector();
}
public void setCornerRadius(int cornerRadius) {
this.cornerRadius = DisplayUtil.dp2px(context, cornerRadius);
setBgSelector();
}
public void setStrokeWidth(int strokeWidth) {
this.strokeWidth = DisplayUtil.dp2px(context, strokeWidth);
setBgSelector();
}
public void setStrokeColor(int strokeColor) {
this.strokeColor = strokeColor;
setBgSelector();
}
public void setIsRadiusHalfHeight(boolean isRadiusHalfHeight) {
this.isRadiusHalfHeight = isRadiusHalfHeight;
setBgSelector();
}
public void setIsWidthHeightEqual(boolean isWidthHeightEqual) {
this.isWidthHeightEqual = isWidthHeightEqual;
setBgSelector();
}
public int getBackgroundColor() {
return backgroundColor;
}
public int getCornerRadius() {
return cornerRadius;
}
public int getStrokeWidth() {
return strokeWidth;
}
public int getStrokeColor() {
return strokeColor;
}
public boolean isRadiusHalfHeight() {
return isRadiusHalfHeight;
}
public boolean isWidthHeightEqual() {
return isWidthHeightEqual;
}
private void setDrawable(GradientDrawable gd, int color, int strokeColor) {
gd.setColor(color);
gd.setCornerRadius(cornerRadius);
gd.setStroke(strokeWidth, strokeColor);
}
public void setBgSelector() {
StateListDrawable bg = new StateListDrawable();
setDrawable(gd_background, backgroundColor, strokeColor);
bg.addState(new int[]{-android.R.attr.state_pressed}, gd_background);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {//16
setBackground(bg);
} else {
//noinspection deprecation
setBackgroundDrawable(bg);
}
}
}

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false">
<TextView
android:id="@+id/tv_tab_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:singleLine="true"/>
<com.mindspore.customview.tablayout.widget.MsgView
android:id="@+id/rtv_msg_tip"
xmlns:mv="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#ffffff"
android:textSize="11.5sp"
android:visibility="gone"
mv:mv_backgroundColor="#FD481F"
mv:mv_isRadiusHalfHeight="true"
mv:mv_strokeColor="#ffffff"
mv:mv_strokeWidth="1dp"/>
</RelativeLayout>

View File

@ -1,45 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false">
<LinearLayout
android:id="@+id/ll_tap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/tv_tab_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"/>
<ImageView
android:id="@+id/iv_tab_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<com.mindspore.customview.tablayout.widget.MsgView
android:id="@+id/rtv_msg_tip"
xmlns:mv="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/ll_tap"
android:gravity="center"
android:textColor="#ffffff"
android:textSize="11.5sp"
android:visibility="gone"
mv:mv_backgroundColor="#FD481F"
mv:mv_isRadiusHalfHeight="true"
mv:mv_strokeColor="#ffffff"
mv:mv_strokeWidth="1dp"/>
</RelativeLayout>

View File

@ -1,44 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false">
<LinearLayout
android:id="@+id/ll_tap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv_tab_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/tv_tab_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"/>
</LinearLayout>
<com.mindspore.customview.tablayout.widget.MsgView
android:layout_toRightOf="@+id/ll_tap"
android:id="@+id/rtv_msg_tip"
xmlns:mv="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#ffffff"
android:textSize="11.5sp"
android:visibility="gone"
mv:mv_backgroundColor="#FD481F"
mv:mv_isRadiusHalfHeight="true"
mv:mv_strokeColor="#ffffff"
mv:mv_strokeWidth="1dp"/>
</RelativeLayout>

View File

@ -1,45 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false">
<LinearLayout
android:id="@+id/ll_tap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_tab_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"/>
<ImageView
android:id="@+id/iv_tab_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<com.mindspore.customview.tablayout.widget.MsgView
android:id="@+id/rtv_msg_tip"
xmlns:mv="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/ll_tap"
android:gravity="center"
android:textColor="#ffffff"
android:textSize="11.5sp"
android:visibility="gone"
mv:mv_backgroundColor="#FD481F"
mv:mv_isRadiusHalfHeight="true"
mv:mv_strokeColor="#ffffff"
mv:mv_strokeWidth="1dp"/>
</RelativeLayout>

View File

@ -1,39 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false">
<LinearLayout
android:id="@+id/ll_tap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_tab_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"/>
</LinearLayout>
<com.mindspore.customview.tablayout.widget.MsgView
android:layout_toRightOf="@+id/ll_tap"
android:id="@+id/rtv_msg_tip"
xmlns:mv="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#ffffff"
android:textSize="11.5sp"
android:visibility="gone"
mv:mv_backgroundColor="#FD481F"
mv:mv_isRadiusHalfHeight="true"
mv:mv_strokeColor="#ffffff"
mv:mv_strokeWidth="1dp"/>
</RelativeLayout>

View File

@ -1,44 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false">
<LinearLayout
android:id="@+id/ll_tap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/iv_tab_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/tv_tab_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"/>
</LinearLayout>
<com.mindspore.customview.tablayout.widget.MsgView
android:id="@+id/rtv_msg_tip"
xmlns:mv="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/ll_tap"
android:gravity="center"
android:textColor="#ffffff"
android:textSize="11.5sp"
android:visibility="gone"
mv:mv_backgroundColor="#FD481F"
mv:mv_isRadiusHalfHeight="true"
mv:mv_strokeColor="#ffffff"
mv:mv_strokeWidth="1dp"/>
</RelativeLayout>

View File

@ -1,163 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="tl_divider_color" format="color" />
<attr name="tl_divider_padding" format="dimension" />
<attr name="tl_divider_width" format="dimension" />
<attr name="tl_indicator_anim_duration" format="integer" />
<attr name="tl_indicator_anim_enable" format="boolean" />
<attr name="tl_indicator_bounce_enable" format="boolean" />
<attr name="tl_indicator_color" format="color" />
<attr name="tl_indicator_corner_radius" format="dimension" />
<attr name="tl_indicator_gravity" format="enum">
<enum name="TOP" value="48" />
<enum name="BOTTOM" value="80" />
</attr>
<attr name="tl_indicator_height" format="dimension" />
<attr name="tl_indicator_margin_bottom" format="dimension" />
<attr name="tl_indicator_margin_left" format="dimension" />
<attr name="tl_indicator_margin_right" format="dimension" />
<attr name="tl_indicator_margin_top" format="dimension" />
<attr name="tl_indicator_style" format="enum">
<enum name="NORMAL" value="0" />
<enum name="TRIANGLE" value="1" />
<enum name="BLOCK" value="2" />
</attr>
<attr name="tl_indicator_width" format="dimension" />
<attr name="tl_indicator_width_equal_title" format="boolean" />
<attr name="tl_tab_padding" format="dimension" />
<attr name="tl_tab_space_equal" format="boolean" />
<attr name="tl_tab_width" format="dimension" />
<attr name="tl_textAllCaps" format="boolean" />
<attr name="tl_textBold" format="enum">
<enum name="NONE" value="0" />
<enum name="SELECT" value="1" />
<enum name="BOTH" value="2" />
</attr>
<attr name="tl_textSelectColor" format="color" />
<attr name="tl_textUnselectColor" format="color" />
<attr name="tl_textsize" format="dimension" />
<attr name="tl_underline_color" format="color" />
<attr name="tl_underline_gravity" format="enum">
<enum name="TOP" value="48" />
<enum name="BOTTOM" value="80" />
</attr>
<attr name="tl_underline_height" format="dimension" />
<declare-styleable name="CommonTabLayout">
<attr name="tl_indicator_color" />
<attr name="tl_indicator_height" />
<attr name="tl_indicator_width" />
<attr name="tl_indicator_margin_left" />
<attr name="tl_indicator_margin_top" />
<attr name="tl_indicator_margin_right" />
<attr name="tl_indicator_margin_bottom" />
<attr name="tl_indicator_corner_radius" />
<attr name="tl_indicator_gravity" />
<attr name="tl_indicator_style" />
<attr name="tl_indicator_anim_enable" />
<attr name="tl_indicator_anim_duration" />
<attr name="tl_indicator_bounce_enable" />
<attr name="tl_underline_color" />
<attr name="tl_underline_height" />
<attr name="tl_underline_gravity" />
<attr name="tl_divider_color" />
<attr name="tl_divider_width" />
<attr name="tl_divider_padding" />
<attr name="tl_tab_padding" />
<attr name="tl_tab_space_equal" />
<attr name="tl_tab_width" />
<attr name="tl_textsize" />
<attr name="tl_textSelectColor" />
<attr name="tl_textUnselectColor" />
<attr name="tl_textBold" />
<attr name="tl_textAllCaps" />
<attr name="tl_iconWidth" format="dimension" />
<attr name="tl_iconHeight" format="dimension" />
<attr name="tl_iconVisible" format="boolean" />
<attr name="tl_iconGravity" format="enum">
<enum name="LEFT" value="3" />
<enum name="TOP" value="48" />
<enum name="RIGHT" value="5" />
<enum name="BOTTOM" value="80" />
</attr>
<attr name="tl_iconMargin" format="dimension" />
</declare-styleable>
<declare-styleable name="MsgView">
<attr name="mv_backgroundColor" format="color" />
<attr name="mv_cornerRadius" format="dimension" />
<attr name="mv_strokeWidth" format="dimension" />
<attr name="mv_strokeColor" format="color" />
<attr name="mv_isRadiusHalfHeight" format="boolean" />
<attr name="mv_isWidthHeightEqual" format="boolean" />
</declare-styleable>
<declare-styleable name="SegmentTabLayout">
<attr name="tl_indicator_color" />
<attr name="tl_indicator_height" />
<attr name="tl_indicator_margin_left" />
<attr name="tl_indicator_margin_top" />
<attr name="tl_indicator_margin_right" />
<attr name="tl_indicator_margin_bottom" />
<attr name="tl_indicator_corner_radius" />
<attr name="tl_indicator_anim_enable" />
<attr name="tl_indicator_anim_duration" />
<attr name="tl_indicator_bounce_enable" />
<attr name="tl_divider_color" />
<attr name="tl_divider_width" />
<attr name="tl_divider_padding" />
<attr name="tl_tab_padding" />
<attr name="tl_tab_space_equal" />
<attr name="tl_tab_width" />
<attr name="tl_textsize" />
<attr name="tl_textSelectColor" />
<attr name="tl_textUnselectColor" />
<attr name="tl_textBold" />
<attr name="tl_textAllCaps" />
<attr name="tl_bar_color" format="color" />
<attr name="tl_bar_stroke_color" format="color" />
<attr name="tl_bar_stroke_width" format="dimension" />
</declare-styleable>
<declare-styleable name="SlidingTabLayout">
<attr name="tl_indicator_color" />
<attr name="tl_indicator_height" />
<attr name="tl_indicator_width" />
<attr name="tl_indicator_margin_left" />
<attr name="tl_indicator_margin_top" />
<attr name="tl_indicator_margin_right" />
<attr name="tl_indicator_margin_bottom" />
<attr name="tl_indicator_corner_radius" />
<attr name="tl_indicator_gravity" />
<attr name="tl_indicator_style" />
<attr name="tl_indicator_width_equal_title" />
<attr name="tl_underline_color" />
<attr name="tl_underline_height" />
<attr name="tl_underline_gravity" />
<attr name="tl_divider_color" />
<attr name="tl_divider_width" />
<attr name="tl_divider_padding" />
<attr name="tl_tab_padding" />
<attr name="tl_tab_space_equal" />
<attr name="tl_tab_width" />
<attr name="tl_textsize" />
<attr name="tl_textSelectColor" />
<attr name="tl_textUnselectColor" />
<attr name="tl_textBold" />
<attr name="tl_textAllCaps" />
</declare-styleable>
<declare-styleable name="CountDownView">
<attr name="cd_circle_radius" format="dimension" />
<attr name="cd_arc_width" format="dimension" />
<attr name="cd_arc_color" format="color" />
<attr name="cd_bg_color" format="color" />
<attr name="cd_text_color" format="color" />
<attr name="cd_text_size" format="dimension" />
<attr name="cd_animator_time" format="integer" />
<attr name="cd_animator_time_unit" format="string" />
<attr name="cd_retreat_type" format="enum">
<declare-styleable name="MSCountDownView">
<attr name="ms_cd_circle_radius" format="dimension" />
<attr name="ms_cd_arc_width" format="dimension" />
<attr name="ms_cd_arc_color" format="color" />
<attr name="ms_cd_bg_color" format="color" />
<attr name="ms_cd_text_color" format="color" />
<attr name="ms_cd_text_size" format="dimension" />
<attr name="ms_cd_animator_time" format="integer" />
<attr name="ms_cd_animator_time_unit" format="string" />
<attr name="ms_cd_retreat_type" format="enum">
<enum name="forward" value="1" />
<enum name="back" value="2" />
</attr>
<attr name="cd_location" format="enum">
<attr name="ms_cd_location" format="enum">
<enum name="left" value="1" />
<enum name="top" value="2" />
<enum name="right" value="3" />

View File

@ -8,27 +8,21 @@ cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_VERBOSE_MAKEFILE on)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI})
set(MINDSPORELITE_VERSION mindspore-lite-1.0.1-runtime-arm64-cpu)
set(MINDSPORELITE_VERSION mindspore-lite-1.1.1-runtime-arm64-cpu)
# ============== Set MindSpore Dependencies. =============
include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp)
include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}/third_party/flatbuffers/include)
include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION})
include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}/include)
include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}/include/ir/dtype)
include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}/include/schema)
include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}/minddata/include)
add_library(mindspore-lite SHARED IMPORTED)
add_library(minddata-lite SHARED IMPORTED)
add_library(libmindspore-lite-fp16 SHARED IMPORTED)
set_target_properties(mindspore-lite PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}/lib/libmindspore-lite.so)
set_target_properties(minddata-lite PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}/minddata/lib/libminddata-lite.so)
set_target_properties(libmindspore-lite-fp16 PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}/lib/libmindspore-lite-fp16.so)
# --------------- MindSpore Lite set End. --------------------
@ -74,7 +68,6 @@ target_link_libraries( # Specifies the target library.
# --- mindspore ---
minddata-lite
mindspore-lite
libmindspore-lite-fp16
# --- other dependencies.---
-ljnigraphics

View File

@ -4,13 +4,13 @@
* The libraries can be downloaded manually.
*/
def targetMindSporeInclude = "src/main/cpp/"
def mindsporeLite_Version = "mindspore-lite-1.0.1-runtime-arm64-cpu"
def mindsporeLite_Version = "mindspore-lite-1.1.1-runtime-arm64-cpu"
def targetModelFile = "src/main/assets/model/mobilenetv2.ms"
def mindSporeLibrary_arm64 = "src/main/cpp/${mindsporeLite_Version}.tar.gz"
def modelDownloadUrl = "https://download.mindspore.cn/model_zoo/official/lite/mobilenetv2_openimage_lite/mobilenetv2.ms"
def mindsporeLiteDownloadUrl = "https://ms-release.obs.cn-north-4.myhuaweicloud.com/1.0.1/lite/android_aarch64/${mindsporeLite_Version}.tar.gz"
def mindsporeLiteDownloadUrl = "https://ms-release.obs.cn-north-4.myhuaweicloud.com/1.1.1/MindSpore/lite/release_0220/android/${mindsporeLite_Version}.tar.gz"
def cleantargetMindSporeInclude = "src/main/cpp"

View File

@ -29,7 +29,6 @@
#include "MSNetWork.h"
#include "lite_cv/lite_mat.h"
#include "lite_cv/image_process.h"
#include "mindspore-lite-1.0.1-runtime-arm64-cpu/minddata/include/lite_cv/lite_mat.h"
using mindspore::dataset::LiteMat;
using mindspore::dataset::LPixelType;

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB