!14624 [MS][Lite]remove some copy codes
From: @sishuikang Reviewed-by: @zhanghaibo5,@zhanghaibo5,@hangangqiang Signed-off-by: @zhanghaibo5
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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" />
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 9.2 KiB |
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |