version:1.1.4
update:更换为竖屏 bugfixes:
1
FlycoTabLayoutZ_Lib/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
38
FlycoTabLayoutZ_Lib/build.gradle
Normal file
@@ -0,0 +1,38 @@
|
||||
apply plugin: 'com.android.library'
|
||||
//apply plugin: 'com.novoda.bintray-release'
|
||||
|
||||
version = "1.3.3"
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
buildToolsVersion "28.0.3"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 17
|
||||
targetSdkVersion 28
|
||||
versionCode 5
|
||||
versionName version
|
||||
}
|
||||
buildTypes {
|
||||
U807Debug {}
|
||||
U807Release {}
|
||||
iPlay50SEDebug {}
|
||||
iPlay50SERelease {}
|
||||
debug {}
|
||||
release {}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
}
|
||||
|
||||
//// jcenter发布的信息
|
||||
//publish {
|
||||
// userOrg = 'lizp' // 创建repo的位置
|
||||
// groupId = 'com.lzp' // 引用的分组名称
|
||||
// artifactId = 'FlycoTabLayoutZ'//项目名称
|
||||
// publishVersion = version//版本号
|
||||
// desc = '在FlycoTabLayout的基础上,扩展出SlidingScaleTabLayout,实现滑动可以改变tab字体的大小的切换效果'
|
||||
// website = 'https://github.com/li504799868/FlycoTabLayoutZ'
|
||||
//}
|
||||
17
FlycoTabLayoutZ_Lib/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /Users/lihui/work/AndroidStudio/sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
3
FlycoTabLayoutZ_Lib/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<manifest
|
||||
package="com.flyco.tablayout">
|
||||
</manifest>
|
||||
@@ -0,0 +1,985 @@
|
||||
package com.flyco.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 androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
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 com.flyco.tablayout.listener.CustomTabEntity;
|
||||
import com.flyco.tablayout.listener.OnTabSelectListener;
|
||||
import com.flyco.tablayout.utils.FragmentChangeManager;
|
||||
import com.flyco.tablayout.utils.UnreadMsgUtils;
|
||||
import com.flyco.tablayout.widget.MsgView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* 没有继承HorizontalScrollView不能滑动,对于ViewPager无依赖
|
||||
*/
|
||||
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 Rect mIndicatorRect = 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 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);//重写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.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,
|
||||
dp2px(mIndicatorStyle == STYLE_TRIANGLE ? 4 : (mIndicatorStyle == STYLE_BLOCK ? -1 : 2)));
|
||||
mIndicatorWidth = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_width, dp2px(mIndicatorStyle == STYLE_TRIANGLE ? 10 : -1));
|
||||
mIndicatorCornerRadius = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_corner_radius, dp2px(mIndicatorStyle == STYLE_BLOCK ? -1 : 0));
|
||||
mIndicatorMarginLeft = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_margin_left, dp2px(0));
|
||||
mIndicatorMarginTop = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_margin_top, dp2px(mIndicatorStyle == STYLE_BLOCK ? 7 : 0));
|
||||
mIndicatorMarginRight = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_margin_right, dp2px(0));
|
||||
mIndicatorMarginBottom = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_margin_bottom, dp2px(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, dp2px(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, dp2px(0));
|
||||
mDividerPadding = ta.getDimension(R.styleable.CommonTabLayout_tl_divider_padding, dp2px(12));
|
||||
|
||||
mTextsize = ta.getDimension(R.styleable.CommonTabLayout_tl_textSize, sp2px(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, dp2px(0));
|
||||
mIconHeight = ta.getDimension(R.styleable.CommonTabLayout_tl_iconHeight, dp2px(0));
|
||||
mIconMargin = ta.getDimension(R.styleable.CommonTabLayout_tl_iconMargin, dp2px(2.5f));
|
||||
|
||||
mTabSpaceEqual = ta.getBoolean(R.styleable.CommonTabLayout_tl_tab_space_equal, true);
|
||||
mTabWidth = ta.getDimension(R.styleable.CommonTabLayout_tl_tab_width, dp2px(-1));
|
||||
mTabPadding = ta.getDimension(R.styleable.CommonTabLayout_tl_tab_padding, mTabSpaceEqual || mTabWidth > 0 ? dp2px(0) : dp2px(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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联数据支持同时切换fragments
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建并添加tab
|
||||
*/
|
||||
private void addTab(final int position, View tabView) {
|
||||
TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
|
||||
tv_tab_title.setText(mTabEntitys.get(position).getTabTitle());
|
||||
ImageView iv_tab_icon = (ImageView) tabView.findViewById(R.id.iv_tab_icon);
|
||||
iv_tab_icon.setImageResource(mTabEntitys.get(position).getTabUnselectedIcon());
|
||||
|
||||
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);
|
||||
// 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_WHEN_SELECT && i == mCurrentTab) {
|
||||
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();
|
||||
|
||||
// Log.d("AAA", "mLastP--->" + mLastP.left + "&" + mLastP.right);
|
||||
// Log.d("AAA", "mCurrentP--->" + mCurrentP.left + "&" + mCurrentP.right);
|
||||
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) { //indicatorWidth小于0时,原jpardogo's PagerSlidingTabStrip
|
||||
|
||||
} else {//indicatorWidth大于0时,圆角矩形以及三角形
|
||||
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) { //indicatorWidth小于0时,原jpardogo's PagerSlidingTabStrip
|
||||
|
||||
} else {//indicatorWidth大于0时,圆角矩形以及三角形
|
||||
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 {
|
||||
/* 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) {
|
||||
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 = dp2px(tabPadding);
|
||||
updateTabStyles();
|
||||
}
|
||||
|
||||
public void setTabSpaceEqual(boolean tabSpaceEqual) {
|
||||
this.mTabSpaceEqual = tabSpaceEqual;
|
||||
updateTabStyles();
|
||||
}
|
||||
|
||||
public void setTabWidth(float tabWidth) {
|
||||
this.mTabWidth = dp2px(tabWidth);
|
||||
updateTabStyles();
|
||||
}
|
||||
|
||||
public void setIndicatorColor(int indicatorColor) {
|
||||
this.mIndicatorColor = indicatorColor;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setIndicatorHeight(float indicatorHeight) {
|
||||
this.mIndicatorHeight = dp2px(indicatorHeight);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setIndicatorWidth(float indicatorWidth) {
|
||||
this.mIndicatorWidth = dp2px(indicatorWidth);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setIndicatorCornerRadius(float indicatorCornerRadius) {
|
||||
this.mIndicatorCornerRadius = dp2px(indicatorCornerRadius);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setIndicatorGravity(int indicatorGravity) {
|
||||
this.mIndicatorGravity = indicatorGravity;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setIndicatorMargin(float indicatorMarginLeft, float indicatorMarginTop,
|
||||
float indicatorMarginRight, float indicatorMarginBottom) {
|
||||
this.mIndicatorMarginLeft = dp2px(indicatorMarginLeft);
|
||||
this.mIndicatorMarginTop = dp2px(indicatorMarginTop);
|
||||
this.mIndicatorMarginRight = dp2px(indicatorMarginRight);
|
||||
this.mIndicatorMarginBottom = dp2px(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 = dp2px(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 = dp2px(dividerWidth);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setDividerPadding(float dividerPadding) {
|
||||
this.mDividerPadding = dp2px(dividerPadding);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setTextsize(float textsize) {
|
||||
this.mTextsize = sp2px(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 = dp2px(iconWidth);
|
||||
updateTabStyles();
|
||||
}
|
||||
|
||||
public void setIconHeight(float iconHeight) {
|
||||
this.mIconHeight = dp2px(iconHeight);
|
||||
updateTabStyles();
|
||||
}
|
||||
|
||||
public void setIconMargin(float iconMargin) {
|
||||
this.mIconMargin = dp2px(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;
|
||||
}
|
||||
|
||||
//setter and getter
|
||||
|
||||
// show MsgTipView
|
||||
private Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private SparseArray<Boolean> mInitSetMap = new SparseArray<>();
|
||||
|
||||
/**
|
||||
* 显示未读消息
|
||||
*
|
||||
* @param position 显示tab位置
|
||||
* @param num num小于等于0显示红点,num大于0显示数字
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示未读红点
|
||||
*
|
||||
* @param position 显示tab位置
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置提示红点偏移,注意
|
||||
* 1.控件为固定高度:参照点为tab内容的右上角
|
||||
* 2.控件高度不固定(WRAP_CONTENT):参照点为tab内容的右上角,此时高度已是红点的最高显示范围,所以这时bottomPadding其实就是topPadding
|
||||
*/
|
||||
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 = dp2px(leftPadding);
|
||||
lp.topMargin = mHeight > 0 ? (int) (mHeight - textHeight - iconH - margin) / 2 - dp2px(bottomPadding) : dp2px(bottomPadding);
|
||||
} else {
|
||||
lp.leftMargin = dp2px(leftPadding);
|
||||
lp.topMargin = mHeight > 0 ? (int) (mHeight - Math.max(textHeight, iconH)) / 2 - dp2px(bottomPadding) : dp2px(bottomPadding);
|
||||
}
|
||||
|
||||
tipView.setLayoutParams(lp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前类只提供了少许设置未读消息属性的方法,可以通过该方法获取MsgView对象从而各种设置
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected int dp2px(float dp) {
|
||||
final float scale = mContext.getResources().getDisplayMetrics().density;
|
||||
return (int) (dp * scale + 0.5f);
|
||||
}
|
||||
|
||||
protected int sp2px(float sp) {
|
||||
final float scale = this.mContext.getResources().getDisplayMetrics().scaledDensity;
|
||||
return (int) (sp * scale + 0.5f);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,775 @@
|
||||
package com.flyco.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 androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
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 com.flyco.tablayout.listener.OnTabSelectListener;
|
||||
import com.flyco.tablayout.utils.FragmentChangeManager;
|
||||
import com.flyco.tablayout.utils.UnreadMsgUtils;
|
||||
import com.flyco.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, dp2px(0));
|
||||
mIndicatorMarginTop = ta.getDimension(R.styleable.SegmentTabLayout_tl_indicator_margin_top, 0);
|
||||
mIndicatorMarginRight = ta.getDimension(R.styleable.SegmentTabLayout_tl_indicator_margin_right, dp2px(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(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, dp2px(1));
|
||||
mDividerPadding = ta.getDimension(R.styleable.SegmentTabLayout_tl_divider_padding, 0);
|
||||
|
||||
mTextsize = ta.getDimension(R.styleable.SegmentTabLayout_tl_textSize, sp2px(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, dp2px(-1));
|
||||
mTabPadding = ta.getDimension(R.styleable.SegmentTabLayout_tl_tab_padding, mTabSpaceEqual || mTabWidth > 0 ? dp2px(0) : dp2px(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, dp2px(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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联数据支持同时切换fragments
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建并添加tab
|
||||
*/
|
||||
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);
|
||||
// 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_WHEN_SELECT && i == mCurrentTab) {
|
||||
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();
|
||||
|
||||
// Log.d("AAA", "mLastP--->" + mLastP.left + "&" + mLastP.right);
|
||||
// Log.d("AAA", "mCurrentP--->" + mCurrentP.left + "&" + mCurrentP.right);
|
||||
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 = dp2px(tabPadding);
|
||||
updateTabStyles();
|
||||
}
|
||||
|
||||
public void setTabSpaceEqual(boolean tabSpaceEqual) {
|
||||
this.mTabSpaceEqual = tabSpaceEqual;
|
||||
updateTabStyles();
|
||||
}
|
||||
|
||||
public void setTabWidth(float tabWidth) {
|
||||
this.mTabWidth = dp2px(tabWidth);
|
||||
updateTabStyles();
|
||||
}
|
||||
|
||||
public void setIndicatorColor(int indicatorColor) {
|
||||
this.mIndicatorColor = indicatorColor;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setIndicatorHeight(float indicatorHeight) {
|
||||
this.mIndicatorHeight = dp2px(indicatorHeight);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setIndicatorCornerRadius(float indicatorCornerRadius) {
|
||||
this.mIndicatorCornerRadius = dp2px(indicatorCornerRadius);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setIndicatorMargin(float indicatorMarginLeft, float indicatorMarginTop,
|
||||
float indicatorMarginRight, float indicatorMarginBottom) {
|
||||
this.mIndicatorMarginLeft = dp2px(indicatorMarginLeft);
|
||||
this.mIndicatorMarginTop = dp2px(indicatorMarginTop);
|
||||
this.mIndicatorMarginRight = dp2px(indicatorMarginRight);
|
||||
this.mIndicatorMarginBottom = dp2px(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 = dp2px(dividerWidth);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setDividerPadding(float dividerPadding) {
|
||||
this.mDividerPadding = dp2px(dividerPadding);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setTextsize(float textsize) {
|
||||
this.mTextsize = sp2px(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<>();
|
||||
|
||||
/**
|
||||
* 显示未读消息
|
||||
*
|
||||
* @param position 显示tab位置
|
||||
* @param num num小于等于0显示红点,num大于0显示数字
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示未读红点
|
||||
*
|
||||
* @param position 显示tab位置
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置提示红点偏移,注意
|
||||
* 1.控件为固定高度:参照点为tab内容的右上角
|
||||
* 2.控件高度不固定(WRAP_CONTENT):参照点为tab内容的右上角,此时高度已是红点的最高显示范围,所以这时bottomPadding其实就是topPadding
|
||||
*/
|
||||
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 = dp2px(leftPadding);
|
||||
lp.topMargin = mHeight > 0 ? (int) (mHeight - textHeight) / 2 - dp2px(bottomPadding) : dp2px(bottomPadding);
|
||||
|
||||
tipView.setLayoutParams(lp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前类只提供了少许设置未读消息属性的方法,可以通过该方法获取MsgView对象从而各种设置
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
protected int dp2px(float dp) {
|
||||
final float scale = mContext.getResources().getDisplayMetrics().density;
|
||||
return (int) (dp * scale + 0.5f);
|
||||
}
|
||||
|
||||
protected int sp2px(float sp) {
|
||||
final float scale = this.mContext.getResources().getDisplayMetrics().scaledDensity;
|
||||
return (int) (sp * scale + 0.5f);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.flyco.tablayout.listener;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
|
||||
public interface CustomTabEntity {
|
||||
String getTabTitle();
|
||||
|
||||
@DrawableRes
|
||||
int getTabSelectedIcon();
|
||||
|
||||
@DrawableRes
|
||||
int getTabUnselectedIcon();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.flyco.tablayout.listener;
|
||||
|
||||
public interface OnTabSelectListener {
|
||||
void onTabSelect(int position);
|
||||
void onTabReselect(int position);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.flyco.tablayout.transformer;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import android.view.View;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by li.zhipeng on 2019/1/3.
|
||||
* <p>
|
||||
* tab切换的
|
||||
*/
|
||||
public class ExtendTransformer implements ViewPager.PageTransformer {
|
||||
|
||||
private ArrayList<IViewPagerTransformer> transformers = new ArrayList<>();
|
||||
|
||||
|
||||
public ExtendTransformer() {
|
||||
}
|
||||
|
||||
public void addViewPagerTransformer(IViewPagerTransformer transformer) {
|
||||
if (!transformers.contains(transformer)) {
|
||||
transformers.add(transformer);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeViewPagerTransformer(IViewPagerTransformer transformer) {
|
||||
transformers.remove(transformer);
|
||||
}
|
||||
|
||||
public List<IViewPagerTransformer> getTransformers() {
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public void setTransformers(List<IViewPagerTransformer> transformers) {
|
||||
this.transformers.addAll(transformers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transformPage(@NonNull View view, final float position) {
|
||||
// 回调设置的页面切换效果设置
|
||||
if (transformers != null && transformers.size() > 0) {
|
||||
for (IViewPagerTransformer transformer : transformers) {
|
||||
transformer.transformPage(view, position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.flyco.tablayout.transformer;
|
||||
|
||||
public interface ITabScaleTransformer {
|
||||
void setNormalWidth(int position, int width, boolean isSelect);
|
||||
void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.flyco.tablayout.transformer;
|
||||
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
/**
|
||||
* Created by li.zhipeng on 2019/1/3.
|
||||
*
|
||||
* ViewPager的扩展Transformer,配合SlidingScaleTabLayout使用
|
||||
* 因为字体的切换效果设置了默认的Transformer,所以扩展此接口
|
||||
*/
|
||||
public interface IViewPagerTransformer extends ViewPager.PageTransformer {
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package com.flyco.tablayout.transformer;
|
||||
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.flyco.tablayout.SlidingScaleTabLayout;
|
||||
|
||||
/**
|
||||
* Created by li.zhipeng on 2019/1/3.
|
||||
* <p>
|
||||
* tab切换的
|
||||
*/
|
||||
public class TabScaleTransformer implements ITabScaleTransformer {
|
||||
|
||||
private SlidingScaleTabLayout slidingScaleTabLayout;
|
||||
|
||||
private float textSelectSize;
|
||||
|
||||
private float textUnSelectSize;
|
||||
|
||||
// private float maxScale;
|
||||
|
||||
private boolean openDmg;
|
||||
|
||||
public TabScaleTransformer(SlidingScaleTabLayout slidingScaleTabLayout,
|
||||
float textSelectSize, float textUnSelectSize, boolean openDmg) {
|
||||
this.slidingScaleTabLayout = slidingScaleTabLayout;
|
||||
this.textSelectSize = textSelectSize;
|
||||
this.textUnSelectSize = textUnSelectSize;
|
||||
// this.maxScale = (textSelectSize / textUnSelectSize) - 1;
|
||||
this.openDmg = openDmg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNormalWidth(int position, int width, boolean isSelect) {
|
||||
}
|
||||
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
Log.i("TabScaleTransformer", "position:" + position);
|
||||
// 字体大小相同,不需要切换
|
||||
if (textSelectSize == textUnSelectSize) return;
|
||||
if (openDmg) {
|
||||
for (int i = 0; i < slidingScaleTabLayout.getTabCount(); i++) {
|
||||
if (i != position && i != position + 1) {
|
||||
changTabDmgWidth(i, 0);
|
||||
}
|
||||
}
|
||||
changeDmgSize(position, positionOffset);
|
||||
} else {
|
||||
for (int i = 0; i < slidingScaleTabLayout.getTabCount(); i++) {
|
||||
if (i != position && i != position + 1) {
|
||||
updateTextSize(i, 1);
|
||||
}
|
||||
}
|
||||
changeTextSize(position, positionOffset);
|
||||
}
|
||||
}
|
||||
|
||||
private void changeTextSize(final int position, final float positionOffset) {
|
||||
updateTextSize(position, positionOffset);
|
||||
if (position + 1 < slidingScaleTabLayout.getTabCount()) {
|
||||
updateTextSize(position + 1, 1 - positionOffset);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTextSize(final int position, final float positionOffset) {
|
||||
final TextView currentTab = slidingScaleTabLayout.getTitle(position);
|
||||
// 必须要在View调用post更新样式,否则可能无效
|
||||
currentTab.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int textSize = (int) (textSelectSize - Math.abs((textSelectSize - textUnSelectSize) * positionOffset));
|
||||
if (currentTab.getTextSize() != textSize) {
|
||||
currentTab.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
|
||||
currentTab.requestLayout();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void changeDmgSize(final int position, final float positionOffset) {
|
||||
slidingScaleTabLayout.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Log.i("lzp", "position:" + position + " positionOffset:" + positionOffset);
|
||||
float scale = 1 - positionOffset;
|
||||
changTabDmgWidth(position, scale);
|
||||
if (position + 1 < slidingScaleTabLayout.getTabCount()) {
|
||||
changTabDmgWidth(position + 1, positionOffset);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void changTabDmgWidth(int position, float scale) {
|
||||
final ImageView currentTabDmg = slidingScaleTabLayout.getDmgView(position);
|
||||
if (currentTabDmg == null) return;
|
||||
if (currentTabDmg.getDrawable() == null) return;
|
||||
ViewGroup.LayoutParams params = currentTabDmg.getLayoutParams();
|
||||
int width = (int) (currentTabDmg.getMinimumWidth() + (currentTabDmg.getMaxWidth() - currentTabDmg.getMinimumWidth()) * scale);
|
||||
if (params.width != width) {
|
||||
params.width = width;
|
||||
currentTabDmg.setLayoutParams(params);
|
||||
}
|
||||
// Log.i("lzp", "position:" + position + " scale:" + scale + " width:" + params.width);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.flyco.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;
|
||||
/** Fragment切换数组 */
|
||||
private ArrayList<Fragment> mFragments;
|
||||
/** 当前选中的Tab */
|
||||
private int mCurrentTab;
|
||||
|
||||
public FragmentChangeManager(FragmentManager fm, int containerViewId, ArrayList<Fragment> fragments) {
|
||||
this.mFragmentManager = fm;
|
||||
this.mContainerViewId = containerViewId;
|
||||
this.mFragments = fragments;
|
||||
initFragments();
|
||||
}
|
||||
|
||||
/** 初始化fragments */
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.flyco.tablayout.utils;
|
||||
|
||||
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.View;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.flyco.tablayout.widget.MsgView;
|
||||
|
||||
/**
|
||||
* 未读消息提示View,显示小红点或者带有数字的红点:
|
||||
* 数字一位,圆
|
||||
* 数字两位,圆角矩形,圆角是高度的一半
|
||||
* 数字超过两位,显示99+
|
||||
*/
|
||||
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 < 10) {//圆
|
||||
lp.width = (int) (18 * dm.density);
|
||||
msgView.setText(num + "");
|
||||
} else if (num < 100) {//圆角矩形,圆角是高度的一半,设置默认padding
|
||||
lp.width = RelativeLayout.LayoutParams.WRAP_CONTENT;
|
||||
msgView.setPadding((int) (6 * dm.density), 0, (int) (6 * dm.density), 0);
|
||||
msgView.setText(num + "");
|
||||
} else {//数字超过两位,显示99+
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.flyco.tablayout.utils;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import androidx.annotation.IdRes;
|
||||
import android.view.View;
|
||||
|
||||
public class ViewUtils {
|
||||
|
||||
public static Bitmap generateViewCacheBitmap(View view) {
|
||||
view.destroyDrawingCache();
|
||||
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
|
||||
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
|
||||
view.measure(widthMeasureSpec, heightMeasureSpec);
|
||||
int width = view.getMeasuredWidth();
|
||||
int height = view.getMeasuredHeight();
|
||||
view.layout(0, 0, width, height);
|
||||
view.setDrawingCacheEnabled(true);
|
||||
view.buildDrawingCache();
|
||||
return Bitmap.createBitmap(view.getDrawingCache());
|
||||
}
|
||||
|
||||
public static View findBrotherView(View view, @IdRes int id, int level) {
|
||||
int count = 0;
|
||||
View temp = view;
|
||||
while (count < level) {
|
||||
View target = temp.findViewById(id);
|
||||
if (target != null) {
|
||||
return target;
|
||||
}
|
||||
count += 1;
|
||||
if (temp.getParent() instanceof View) {
|
||||
temp = (View) temp.getParent();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
package com.flyco.tablayout.widget;
|
||||
|
||||
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.flyco.tablayout.R;
|
||||
|
||||
/** 用于需要圆角矩形框背景的TextView的情况,减少直接使用TextView时引入的shape资源文件 */
|
||||
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 = dp2px(cornerRadius);
|
||||
setBgSelector();
|
||||
}
|
||||
|
||||
public void setStrokeWidth(int strokeWidth) {
|
||||
this.strokeWidth = dp2px(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;
|
||||
}
|
||||
|
||||
protected int dp2px(float dp) {
|
||||
final float scale = context.getResources().getDisplayMetrics().density;
|
||||
return (int) (dp * scale + 0.5f);
|
||||
}
|
||||
|
||||
protected int sp2px(float sp) {
|
||||
final float scale = this.context.getResources().getDisplayMetrics().scaledDensity;
|
||||
return (int) (sp * scale + 0.5f);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
38
FlycoTabLayoutZ_Lib/src/main/res/layout/layout_scale_tab.xml
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
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:includeFontPadding="false"
|
||||
tools:text="111"
|
||||
android:singleLine="true" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/tv_tab_title_dmg"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:adjustViewBounds="true" />
|
||||
|
||||
<com.flyco.tablayout.widget.MsgView xmlns:mv="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/rtv_msg_tip"
|
||||
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"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</RelativeLayout>
|
||||
31
FlycoTabLayoutZ_Lib/src/main/res/layout/layout_tab.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<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.flyco.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>
|
||||
@@ -0,0 +1,45 @@
|
||||
<?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.flyco.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>
|
||||
44
FlycoTabLayoutZ_Lib/src/main/res/layout/layout_tab_left.xml
Normal file
@@ -0,0 +1,44 @@
|
||||
<?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.flyco.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>
|
||||
45
FlycoTabLayoutZ_Lib/src/main/res/layout/layout_tab_right.xml
Normal file
@@ -0,0 +1,45 @@
|
||||
<?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.flyco.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>
|
||||
@@ -0,0 +1,39 @@
|
||||
<?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.flyco.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>
|
||||
44
FlycoTabLayoutZ_Lib/src/main/res/layout/layout_tab_top.xml
Normal file
@@ -0,0 +1,44 @@
|
||||
<?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.flyco.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>
|
||||
319
FlycoTabLayoutZ_Lib/src/main/res/values/attrs.xml
Normal file
@@ -0,0 +1,319 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- indicator -->
|
||||
<!-- 设置显示器颜色 -->
|
||||
<attr name="tl_indicator_color" format="color" />
|
||||
<!-- 设置显示器高度 -->
|
||||
<attr name="tl_indicator_height" format="dimension" />
|
||||
<!-- 设置显示器固定宽度 -->
|
||||
<attr name="tl_indicator_width" format="dimension" />
|
||||
<!-- 设置显示器margin,当indicator_width大于0,无效 -->
|
||||
<attr name="tl_indicator_margin_left" format="dimension" />
|
||||
<attr name="tl_indicator_margin_top" format="dimension" />
|
||||
<attr name="tl_indicator_margin_right" format="dimension" />
|
||||
<attr name="tl_indicator_margin_bottom" format="dimension" />
|
||||
<!-- 设置显示器圆角弧度-->
|
||||
<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_style" format="enum">
|
||||
<enum name="NORMAL" value="0" />
|
||||
<enum name="TRIANGLE" value="1" />
|
||||
<enum name="BLOCK" value="2" />
|
||||
</attr>
|
||||
<!-- 设置显示器长度与title一样长,只有在STYLE_NORMAL并且indicatorWidth小于零有效-->
|
||||
<attr name="tl_indicator_width_equal_title" format="boolean" />
|
||||
<!-- 设置显示器支持动画-->
|
||||
<attr name="tl_indicator_anim_enable" format="boolean" />
|
||||
<!-- 设置显示器动画时间-->
|
||||
<attr name="tl_indicator_anim_duration" format="integer" />
|
||||
<!-- 设置显示器支持动画回弹效果-->
|
||||
<attr name="tl_indicator_bounce_enable" format="boolean" />
|
||||
|
||||
<!-- underline -->
|
||||
<!-- 设置下划线颜色 -->
|
||||
<attr name="tl_underline_color" format="color" />
|
||||
<!-- 设置下划线高度 -->
|
||||
<attr name="tl_underline_height" format="dimension" />
|
||||
<!-- 设置下划线上方还是下方-->
|
||||
<attr name="tl_underline_gravity" format="enum">
|
||||
<enum name="TOP" value="48" />
|
||||
<enum name="BOTTOM" value="80" />
|
||||
</attr>
|
||||
|
||||
<!-- divider -->
|
||||
<!-- 设置分割线颜色 -->
|
||||
<attr name="tl_divider_color" format="color" />
|
||||
<!-- 设置分割线宽度 -->
|
||||
<attr name="tl_divider_width" format="dimension" />
|
||||
<!-- 设置分割线的paddingTop和paddingBottom -->
|
||||
<attr name="tl_divider_padding" format="dimension" />
|
||||
|
||||
<!-- tab -->
|
||||
<!-- 设置tab的paddingLeft和paddingRight -->
|
||||
<attr name="tl_tab_padding" format="dimension" />
|
||||
<!-- 设置tab大小等分 -->
|
||||
<attr name="tl_tab_space_equal" format="boolean" />
|
||||
<!-- 设置tab固定大小 -->
|
||||
<attr name="tl_tab_width" format="dimension" />
|
||||
|
||||
<!-- 设置tab的上下间距 -->
|
||||
<attr name="tl_tab_marginTop" format="dimension" />
|
||||
<attr name="tl_tab_marginBottom" format="dimension" />
|
||||
|
||||
<attr name="tl_tab_msg_marginTop" format="dimension" />
|
||||
<attr name="tl_tab_msg_marginRight" format="dimension" />
|
||||
|
||||
<attr name="tl_tab_dot_marginTop" format="dimension" />
|
||||
<attr name="tl_tab_dot_marginRight" format="dimension" />
|
||||
|
||||
<attr name="tl_tab_background" format="reference" />
|
||||
|
||||
<!-- tab的位置 -->
|
||||
<attr name="tl_tab_gravity" format="enum">
|
||||
<enum name="Top" value="0" />
|
||||
<enum name="Bottom" value="1" />
|
||||
<enum name="Center" value="2" />
|
||||
</attr>
|
||||
|
||||
<!-- tab的竖直位置 -->
|
||||
<attr name="tl_tab_vertical_gravity" format="enum">
|
||||
<enum name="Top" value="0" />
|
||||
<enum name="Bottom" value="1" />
|
||||
<enum name="Center" value="2" />
|
||||
</attr>
|
||||
|
||||
<!-- tab的水平位置 -->
|
||||
<attr name="tl_tab_horizontal_gravity" format="enum">
|
||||
<enum name="Left" value="0" />
|
||||
<enum name="Right" value="1" />
|
||||
<enum name="Center" value="2" />
|
||||
</attr>
|
||||
|
||||
<!-- title -->
|
||||
<!-- 设置字体大小 -->
|
||||
<attr name="tl_textSize" format="dimension" />
|
||||
<attr name="tl_textSelectSize" format="dimension" />
|
||||
<attr name="tl_textUnSelectSize" format="dimension" />
|
||||
<!-- 设置字体选中颜色 -->
|
||||
<attr name="tl_textSelectColor" format="color" />
|
||||
<!-- 设置字体未选中颜色 -->
|
||||
<attr name="tl_textUnSelectColor" format="color" />
|
||||
<!-- 设置字体加粗 -->
|
||||
<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_textAllCaps" format="boolean" />
|
||||
|
||||
<declare-styleable name="SlidingTabLayout">
|
||||
<!-- indicator -->
|
||||
<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" />
|
||||
|
||||
<!-- underline -->
|
||||
<attr name="tl_underline_color" />
|
||||
<attr name="tl_underline_height" />
|
||||
<attr name="tl_underline_gravity" />
|
||||
|
||||
<!-- divider -->
|
||||
<attr name="tl_divider_color" />
|
||||
<attr name="tl_divider_width" />
|
||||
<attr name="tl_divider_padding" />
|
||||
|
||||
<!-- tab -->
|
||||
<attr name="tl_tab_padding" />
|
||||
<attr name="tl_tab_space_equal" />
|
||||
<attr name="tl_tab_width" />
|
||||
<attr name="tl_tab_marginTop" />
|
||||
<attr name="tl_tab_marginBottom" />
|
||||
<attr name="tl_tab_gravity" />
|
||||
|
||||
<!-- title -->
|
||||
<attr name="tl_textSelectSize" />
|
||||
<attr name="tl_textUnSelectSize" />
|
||||
<attr name="tl_textSelectColor" />
|
||||
<attr name="tl_textUnSelectColor" />
|
||||
<attr name="tl_textBold" />
|
||||
<attr name="tl_textAllCaps" />
|
||||
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="CommonTabLayout">
|
||||
<!-- indicator -->
|
||||
<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" />
|
||||
|
||||
<!-- underline -->
|
||||
<attr name="tl_underline_color" />
|
||||
<attr name="tl_underline_height" />
|
||||
<attr name="tl_underline_gravity" />
|
||||
|
||||
<!-- divider -->
|
||||
<attr name="tl_divider_color" />
|
||||
<attr name="tl_divider_width" />
|
||||
<attr name="tl_divider_padding" />
|
||||
|
||||
<!-- tab -->
|
||||
<attr name="tl_tab_padding" />
|
||||
<attr name="tl_tab_space_equal" />
|
||||
<attr name="tl_tab_width" />
|
||||
|
||||
<!-- title -->
|
||||
<attr name="tl_textSize" />
|
||||
<attr name="tl_textSelectColor" />
|
||||
<attr name="tl_textUnSelectColor" />
|
||||
<attr name="tl_textBold" />
|
||||
<attr name="tl_textAllCaps" />
|
||||
|
||||
<!-- icon -->
|
||||
<!-- 设置icon宽度 -->
|
||||
<attr name="tl_iconWidth" format="dimension" />
|
||||
<!-- 设置icon高度 -->
|
||||
<attr name="tl_iconHeight" format="dimension" />
|
||||
<!-- 设置icon是否可见 -->
|
||||
<attr name="tl_iconVisible" format="boolean" />
|
||||
<!-- 设置icon显示位置,对应Gravity中常量值 -->
|
||||
<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>
|
||||
<!-- 设置icon与文字间距 -->
|
||||
<attr name="tl_iconMargin" format="dimension" />
|
||||
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="SegmentTabLayout">
|
||||
<!-- indicator -->
|
||||
<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" />
|
||||
|
||||
<!-- divider -->
|
||||
<attr name="tl_divider_color" />
|
||||
<attr name="tl_divider_width" />
|
||||
<attr name="tl_divider_padding" />
|
||||
|
||||
<!-- tab -->
|
||||
<attr name="tl_tab_padding" />
|
||||
<attr name="tl_tab_space_equal" />
|
||||
<attr name="tl_tab_width" />
|
||||
|
||||
<!-- title -->
|
||||
<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="SlidingScaleTabLayout">
|
||||
<!-- indicator -->
|
||||
<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" />
|
||||
|
||||
<!-- underline -->
|
||||
<attr name="tl_underline_color" />
|
||||
<attr name="tl_underline_height" />
|
||||
<attr name="tl_underline_gravity" />
|
||||
|
||||
<!-- divider -->
|
||||
<attr name="tl_divider_color" />
|
||||
<attr name="tl_divider_width" />
|
||||
<attr name="tl_divider_padding" />
|
||||
|
||||
<!-- tab -->
|
||||
<attr name="tl_tab_padding" />
|
||||
<attr name="tl_tab_space_equal" />
|
||||
<attr name="tl_tab_width" />
|
||||
<attr name="tl_tab_marginTop" />
|
||||
<attr name="tl_tab_marginBottom" />
|
||||
<attr name="tl_tab_horizontal_gravity" />
|
||||
<attr name="tl_tab_vertical_gravity" />
|
||||
<attr name="tl_tab_background" />
|
||||
|
||||
<!-- title -->
|
||||
<attr name="tl_textSelectSize" />
|
||||
<attr name="tl_textUnSelectSize" />
|
||||
<attr name="tl_textSelectColor" />
|
||||
<attr name="tl_textUnSelectColor" />
|
||||
<attr name="tl_textBold" />
|
||||
<attr name="tl_textAllCaps" />
|
||||
|
||||
<!-- 是否开启文字的图片镜像 -->
|
||||
<attr name="tl_openTextDmg" format="boolean" />
|
||||
|
||||
<!-- 未读消息的位置 -->
|
||||
<attr name="tl_tab_msg_marginTop" />
|
||||
<attr name="tl_tab_msg_marginRight" />
|
||||
|
||||
<!-- 红点的位置 -->
|
||||
<attr name="tl_tab_dot_marginTop" />
|
||||
<attr name="tl_tab_dot_marginRight" />
|
||||
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="MsgView">
|
||||
<!-- 圆角矩形背景色 -->
|
||||
<attr name="mv_backgroundColor" format="color" />
|
||||
<!-- 圆角弧度,单位dp-->
|
||||
<attr name="mv_cornerRadius" format="dimension" />
|
||||
<!-- 圆角弧度,单位dp-->
|
||||
<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>
|
||||
</resources>
|
||||
@@ -16,8 +16,8 @@ android {
|
||||
applicationId "com.uiui.videoplayer"
|
||||
minSdkVersion 24
|
||||
targetSdkVersion 28
|
||||
versionCode 114
|
||||
versionName "1.1.3"
|
||||
versionCode 115
|
||||
versionName "1.1.4"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
@@ -32,6 +32,14 @@ android {
|
||||
checkReleaseBuilds false
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
viewBinding{
|
||||
enabled = true
|
||||
}
|
||||
|
||||
dataBinding {
|
||||
enabled true
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
@@ -123,6 +131,7 @@ android {
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
|
||||
implementation project(path: ':FlycoTabLayoutZ_Lib')
|
||||
implementation project(path: ':JZVideo')
|
||||
implementation project(path: ':niceimageview')
|
||||
|
||||
@@ -130,6 +139,7 @@ dependencies {
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||
implementation "androidx.viewpager2:viewpager2:1.0.0"
|
||||
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<activity
|
||||
android:name=".activity.main.MainActivity"
|
||||
android:exported="true"
|
||||
android:screenOrientation="userLandscape"
|
||||
android:screenOrientation="portrait"
|
||||
android:launchMode="singleTask" />
|
||||
<activity
|
||||
android:name=".activity.video.VideoActivity"
|
||||
@@ -29,7 +29,7 @@
|
||||
android:name=".activity.preview.PreviewActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="userPortrait" />
|
||||
android:screenOrientation="portrait" />
|
||||
<activity
|
||||
android:name=".activity.PlayActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
@@ -39,6 +39,13 @@
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:screenOrientation="sensor"
|
||||
android:theme="@style/Theme.AppCompat.NoActionBar" />
|
||||
<activity
|
||||
android:name=".activity.vip.VipActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@style/activity_styles"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -1,12 +1,5 @@
|
||||
package com.uiui.videoplayer.activity.main;
|
||||
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
@@ -17,23 +10,24 @@ import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.uiui.videoplayer.BuildConfig;
|
||||
import com.uiui.videoplayer.R;
|
||||
import com.uiui.videoplayer.base.BaseActivity;
|
||||
import com.uiui.videoplayer.base.BaseLightActivity;
|
||||
import com.uiui.videoplayer.bean.BaseResponse;
|
||||
import com.uiui.videoplayer.bean.SpaceInfo;
|
||||
import com.uiui.videoplayer.fragment.doc.DocFragment;
|
||||
import com.uiui.videoplayer.activity.vip.VipActivity;
|
||||
import com.uiui.videoplayer.base.BaseFragmentPagerAdapter;
|
||||
import com.uiui.videoplayer.base.mvvm.BaseMvvmActivity;
|
||||
import com.uiui.videoplayer.databinding.ActivityMainBinding;
|
||||
import com.uiui.videoplayer.fragment.pic.PictureFragment;
|
||||
import com.uiui.videoplayer.fragment.video.VideoFragment;
|
||||
import com.uiui.videoplayer.network.NetInterfaceManager;
|
||||
import com.uiui.videoplayer.utils.JGYUtils;
|
||||
import com.uiui.videoplayer.utils.ToastUtil;
|
||||
import com.uiui.videoplayer.utils.Utils;
|
||||
import com.uiui.videoplayer.utils.VideoUtils;
|
||||
|
||||
import java.io.File;
|
||||
@@ -43,41 +37,18 @@ import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.rxjava3.annotations.NonNull;
|
||||
import io.reactivex.rxjava3.core.Observer;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
|
||||
public class MainActivity extends BaseActivity {
|
||||
public class MainActivity extends BaseMvvmActivity<MainViewModel, ActivityMainBinding> {
|
||||
private static final int REQUEST_PERMISSION_CODE = 200;
|
||||
|
||||
@BindView(R.id.iv_back)
|
||||
ImageView iv_back;
|
||||
@BindView(R.id.cl_pic)
|
||||
ConstraintLayout cl_pic;
|
||||
@BindView(R.id.cl_video)
|
||||
ConstraintLayout cl_video;
|
||||
@BindView(R.id.cl_doc)
|
||||
ConstraintLayout cl_doc;
|
||||
@BindView(R.id.iv_pic)
|
||||
ImageView iv_pic;
|
||||
@BindView(R.id.iv_video)
|
||||
ImageView iv_video;
|
||||
@BindView(R.id.iv_doc)
|
||||
ImageView iv_doc;
|
||||
@BindView(R.id.tv_space)
|
||||
TextView tv_space;
|
||||
@BindView(R.id.tv_rank)
|
||||
TextView tv_rank;
|
||||
|
||||
@BindView(R.id.tv_version)
|
||||
TextView tv_version;
|
||||
private String[] title = new String[]{"视频", "照片"};
|
||||
|
||||
private BaseFragmentPagerAdapter mPagerAdapter;
|
||||
private FragmentManager mFragmentManager;
|
||||
private Fragment[] mFragments;
|
||||
private List<Fragment> mFragments;
|
||||
private PictureFragment mPictureFragment;
|
||||
private VideoFragment mVideoFragment;
|
||||
|
||||
String[] permissions = new String[]{
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
@@ -89,46 +60,41 @@ public class MainActivity extends BaseActivity {
|
||||
return R.layout.activity_main;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean setNightMode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initDataBinding() {
|
||||
mViewModel.setCtx(this);
|
||||
mViewModel.setVDBinding(mViewDataBinding);
|
||||
mViewModel.setLifecycle(getLifecycleSubject());
|
||||
mViewDataBinding.setClick(new Click());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initView() {
|
||||
// getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
// //注意要清除 FLAG_TRANSLUCENT_STATUS flag
|
||||
// getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||||
// getWindow().setStatusBarColor(getResources().getColor(R.color.colorPrimaryDark));
|
||||
ButterKnife.bind(this);
|
||||
tv_version.setText("版本号:V" + BuildConfig.VERSION_NAME);
|
||||
iv_back.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
cl_pic.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
switchContent(0);
|
||||
}
|
||||
});
|
||||
cl_video.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
switchContent(1);
|
||||
}
|
||||
});
|
||||
cl_doc.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
switchContent(2);
|
||||
}
|
||||
});
|
||||
mViewDataBinding.tvVersion.setText("V" + BuildConfig.VERSION_NAME);
|
||||
mFragments = new ArrayList<>();
|
||||
if (mVideoFragment == null) {
|
||||
mVideoFragment = new VideoFragment();
|
||||
}
|
||||
if (mPictureFragment == null) {
|
||||
mPictureFragment = new PictureFragment();
|
||||
}
|
||||
mFragments.add(mVideoFragment);
|
||||
mFragments.add(mPictureFragment);
|
||||
mFragmentManager = getSupportFragmentManager();
|
||||
mFragments = new Fragment[3];
|
||||
switchContent(0);
|
||||
mPagerAdapter = new BaseFragmentPagerAdapter(mFragmentManager, mFragments);
|
||||
mViewDataBinding.viewPager.setAdapter(mPagerAdapter);
|
||||
mViewDataBinding.mainSlidingTabLayout.setViewPager(mViewDataBinding.viewPager, title);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initData() {
|
||||
getHomeSpaceInfo();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -177,124 +143,6 @@ public class MainActivity extends BaseActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private void getHomeSpaceInfo() {
|
||||
NetInterfaceManager.getInstance().getHomeSpaceInfoControl()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<BaseResponse<SpaceInfo>>() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
Log.e("getHomeSpaceInfo", "onSubscribe: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull BaseResponse<SpaceInfo> spaceInfoBaseResponse) {
|
||||
Log.e("getHomeSpaceInfo", "onNext: " + spaceInfoBaseResponse);
|
||||
if (spaceInfoBaseResponse.code == 200) {
|
||||
SpaceInfo spaceInfo = spaceInfoBaseResponse.data;
|
||||
String home_video_grade = spaceInfo.getHome_video_grade();
|
||||
long quota = spaceInfo.getQuota();
|
||||
long use_quota = spaceInfo.getUse_quota();
|
||||
tv_rank.setText(home_video_grade);
|
||||
tv_space.setText(Utils.formatFileSize(use_quota) + "/" + Utils.formatFileSize(quota));
|
||||
} else {
|
||||
tv_rank.setText("普通");
|
||||
tv_space.setText("0GB/0GB");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
Log.e("getHomeSpaceInfo", "onError: " + e.getMessage());
|
||||
onComplete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Log.e("getHomeSpaceInfo", "onComplete: ");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 切换显示内容
|
||||
public void switchContent(int index) {
|
||||
switchPic(index);
|
||||
FragmentTransaction transaction = mFragmentManager.beginTransaction();
|
||||
hideFragments(transaction);
|
||||
try {
|
||||
switch (index) {
|
||||
case 0:
|
||||
if (mFragments[0] == null) {
|
||||
mFragments[0] = new PictureFragment();
|
||||
transaction.add(R.id.content, mFragments[0], 0 + "");
|
||||
} else {
|
||||
transaction.show(mFragments[0]);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (mFragments[1] == null) {
|
||||
mFragments[1] = new VideoFragment();
|
||||
transaction.add(R.id.content, mFragments[1], 1 + "");
|
||||
} else {
|
||||
transaction.show(mFragments[1]);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (mFragments[2] == null) {
|
||||
mFragments[2] = new DocFragment();
|
||||
transaction.add(R.id.content, mFragments[2], 2 + "");
|
||||
} else {
|
||||
transaction.show(mFragments[2]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
transaction.commit();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void switchPic(int index) {
|
||||
// iv_pic.setImageDrawable(getDrawable(R.drawable.home_icon_picture_normal));
|
||||
// iv_video.setImageDrawable(getDrawable(R.drawable.home_icon_video_normal));
|
||||
// iv_doc.setImageDrawable(getDrawable(R.drawable.home_icon_doc_normal));
|
||||
// Animation animation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.anim_small);
|
||||
cl_pic.setBackground(null);
|
||||
cl_video.setBackground(null);
|
||||
cl_doc.setBackground(null);
|
||||
switch (index) {
|
||||
case 0:
|
||||
// iv_pic.startAnimation(animation);
|
||||
iv_pic.setImageDrawable(getDrawable(R.drawable.home_icon_picture_pressed));
|
||||
iv_video.setImageDrawable(getDrawable(R.drawable.home_icon_video_normal));
|
||||
cl_pic.setBackground(getDrawable(R.drawable.alarm_pressed_background));
|
||||
break;
|
||||
case 1:
|
||||
// iv_video.startAnimation(animation);
|
||||
iv_pic.setImageDrawable(getDrawable(R.drawable.home_icon_picture_normal));
|
||||
iv_video.setImageDrawable(getDrawable(R.drawable.home_icon_video_pressed));
|
||||
cl_video.setBackground(getDrawable(R.drawable.alarm_pressed_background));
|
||||
break;
|
||||
case 2:
|
||||
// iv_doc.startAnimation(animation);
|
||||
// iv_doc.setImageDrawable(getDrawable(R.drawable.home_icon_doc_checked));
|
||||
cl_doc.setBackground(getDrawable(R.drawable.alarm_pressed_background));
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
// 将所有的Fragment都置为隐藏状态。
|
||||
private void hideFragments(FragmentTransaction transaction) {
|
||||
if (mFragments != null) {
|
||||
for (Fragment fragment : mFragments) {
|
||||
if (fragment != null) {
|
||||
transaction.hide(fragment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void getThumbnail() {
|
||||
long s1 = System.currentTimeMillis();
|
||||
@@ -346,92 +194,8 @@ public class MainActivity extends BaseActivity {
|
||||
Log.e("getThumbnail", "videoFileList: " + videoFileList);
|
||||
Log.e("getThumbnail", "picFileList size = " + picFileList.size());
|
||||
Log.e("getThumbnail", "videoFileList size = " + videoFileList.size());
|
||||
// if (picFileList.size() == 0) {
|
||||
// nv_pic.setImageDrawable(getDrawable(R.drawable.icon_pic));
|
||||
// } else {
|
||||
// nv_pic.setImageDrawable(path2Drawable(picFileList.get(0)));
|
||||
// }
|
||||
// if (videoFileList.size() == 0) {
|
||||
// nv_video.setImageDrawable(getDrawable(R.drawable.icon_video));
|
||||
// } else {
|
||||
// Observable.create(new ObservableOnSubscribe<Bitmap>() {
|
||||
// @Override
|
||||
// public void subscribe(ObservableEmitter<Bitmap> emitter) throws Exception {
|
||||
// FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
|
||||
// mmr.setDataSource(videoFileList.get(0));
|
||||
// Bitmap bitmap = mmr.getFrameAtTime();//获得视频第一帧的Bitmap对象.
|
||||
// mmr.release();
|
||||
// emitter.onNext(bitmap);
|
||||
// }
|
||||
// }).subscribeOn(Schedulers.newThread())
|
||||
// .observeOn(AndroidSchedulers.mainThread())
|
||||
// .subscribe(new Observer<Bitmap>() {
|
||||
// @Override
|
||||
// public void onSubscribe(Disposable d) {
|
||||
// Log.e("VideoResult", "onSubscribe: ");
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onNext(Bitmap result) {
|
||||
// Log.e("VideoResult", "onNext: " + result);
|
||||
// nv_video.setImageBitmap(result);
|
||||
//// Glide.with(nv_video).load(result).error(R.drawable.icon_video).into(nv_video);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onError(Throwable e) {
|
||||
// Log.e("VideoResult", "onError: " + e.getMessage());
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onComplete() {
|
||||
// Log.e("VideoResult", "onComplete: ");
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
Log.e("getThumbnail", "videoFileList size = " + videoFileList.size());
|
||||
// CombineBitmap.init(this)
|
||||
// .setLayoutManager(new DingLayoutManager()) // 必选, 设置图片的组合形式,支持WechatLayoutManager、DingLayoutManager
|
||||
// .setSize(100) // 必选,组合后Bitmap的尺寸,单位dp
|
||||
// .setGap(1) // 单个图片之间的距离,单位dp,默认0dp
|
||||
//// .setGapColor() // 单个图片间距的颜色,默认白色
|
||||
//// .setPlaceholder() // 单个图片加载失败的默认显示图片
|
||||
// .setUrls(picFileList.toArray(new String[picFileList.size()])) // 要加载的图片url数组
|
||||
// .setBitmaps() // 要加载的图片bitmap数组
|
||||
// .setResourceIds() // 要加载的图片资源id数组
|
||||
// .setImageView(nv_pic) // 直接设置要显示图片的ImageView
|
||||
// // 设置“子图片”的点击事件,需使用setImageView(),index和图片资源数组的索引对应
|
||||
//// .setOnSubItemClickListener(new OnSubItemClickListener() {
|
||||
//// @Override
|
||||
//// public void onSubItemClick(int index) {
|
||||
////
|
||||
//// }
|
||||
//// })
|
||||
//// // 加载进度的回调函数,如果不使用setImageView()方法,可在onComplete()完成最终图片的显示
|
||||
//// .setProgressListener(new ProgressListener() {
|
||||
//// @Override
|
||||
//// public void onStart() {
|
||||
////
|
||||
//// }
|
||||
////
|
||||
//// @Override
|
||||
//// public void onComplete(Bitmap bitmap) {
|
||||
////
|
||||
//// }
|
||||
//// })
|
||||
// .build();
|
||||
|
||||
// CombineBitmap.init(this)
|
||||
// .setLayoutManager(new DingLayoutManager()) // 必选, 设置图片的组合形式,支持WechatLayoutManager、DingLayoutManager
|
||||
// .setSize(100) // 必选,组合后Bitmap的尺寸,单位dp
|
||||
// .setGap(1) // 单个图片之间的距离,单位dp,默认0dp
|
||||
//// .setGapColor() // 单个图片间距的颜色,默认白色
|
||||
//// .setPlaceholder() // 单个图片加载失败的默认显示图片
|
||||
// .setUrls(videoFileList.toArray(new String[videoFileList.size()])) // 要加载的图片url数组
|
||||
// .setBitmaps() // 要加载的图片bitmap数组
|
||||
// .setResourceIds() // 要加载的图片资源id数组
|
||||
// .setImageView(nv_video) // 直接设置要显示图片的ImageView
|
||||
// .build();
|
||||
Log.e("getThumbnail", "videoFileList size = " + videoFileList.size());
|
||||
}
|
||||
|
||||
|
||||
@@ -456,4 +220,34 @@ public class MainActivity extends BaseActivity {
|
||||
|
||||
return drawable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == KeyEvent.ACTION_DOWN) {
|
||||
lazyExit();
|
||||
return true;
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
private long mPreClickTime;
|
||||
|
||||
private void lazyExit() {
|
||||
if (System.currentTimeMillis() - mPreClickTime > 3000) {
|
||||
ToastUtil.show("再按一次,退出");
|
||||
mPreClickTime = System.currentTimeMillis();
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
public class Click {
|
||||
public void exit(View view) {
|
||||
lazyExit();
|
||||
}
|
||||
|
||||
public void toVip(View view) {
|
||||
startActivity(new Intent(MainActivity.this, VipActivity.class));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.uiui.videoplayer.activity.main;
|
||||
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.uiui.videoplayer.base.mvvm.BaseViewModel;
|
||||
import com.uiui.videoplayer.bean.SpaceInfo;
|
||||
import com.uiui.videoplayer.databinding.ActivityMainBinding;
|
||||
|
||||
public class MainViewModel extends BaseViewModel<ActivityMainBinding> {
|
||||
@Override
|
||||
public ActivityMainBinding getVDBinding() {
|
||||
return binding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,463 @@
|
||||
package com.uiui.videoplayer.activity.main.land;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
||||
import com.uiui.videoplayer.BuildConfig;
|
||||
import com.uiui.videoplayer.R;
|
||||
import com.uiui.videoplayer.base.BaseActivity;
|
||||
import com.uiui.videoplayer.bean.BaseResponse;
|
||||
import com.uiui.videoplayer.bean.SpaceInfo;
|
||||
import com.uiui.videoplayer.fragment.doc.DocFragment;
|
||||
import com.uiui.videoplayer.fragment.pic.PictureFragment;
|
||||
import com.uiui.videoplayer.fragment.video.VideoFragment;
|
||||
import com.uiui.videoplayer.network.NetInterfaceManager;
|
||||
import com.uiui.videoplayer.utils.JGYUtils;
|
||||
import com.uiui.videoplayer.utils.ToastUtil;
|
||||
import com.uiui.videoplayer.utils.Utils;
|
||||
import com.uiui.videoplayer.utils.VideoUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.rxjava3.annotations.NonNull;
|
||||
import io.reactivex.rxjava3.core.Observer;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
|
||||
public class LandMainActivity extends BaseActivity {
|
||||
private static final int REQUEST_PERMISSION_CODE = 200;
|
||||
|
||||
@BindView(R.id.iv_back)
|
||||
ImageView iv_back;
|
||||
@BindView(R.id.cl_pic)
|
||||
ConstraintLayout cl_pic;
|
||||
@BindView(R.id.cl_video)
|
||||
ConstraintLayout cl_video;
|
||||
@BindView(R.id.cl_doc)
|
||||
ConstraintLayout cl_doc;
|
||||
@BindView(R.id.iv_pic)
|
||||
ImageView iv_pic;
|
||||
@BindView(R.id.iv_video)
|
||||
ImageView iv_video;
|
||||
@BindView(R.id.iv_doc)
|
||||
ImageView iv_doc;
|
||||
@BindView(R.id.tv_space)
|
||||
TextView tv_space;
|
||||
@BindView(R.id.tv_rank)
|
||||
TextView tv_rank;
|
||||
|
||||
@BindView(R.id.tv_version)
|
||||
TextView tv_version;
|
||||
|
||||
private FragmentManager mFragmentManager;
|
||||
private Fragment[] mFragments;
|
||||
|
||||
String[] permissions = new String[]{
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
};
|
||||
|
||||
@Override
|
||||
public int getLayoutId() {
|
||||
return R.layout.activity_main;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean setNightMode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initView() {
|
||||
// getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
// //注意要清除 FLAG_TRANSLUCENT_STATUS flag
|
||||
// getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||||
// getWindow().setStatusBarColor(getResources().getColor(R.color.colorPrimaryDark));
|
||||
ButterKnife.bind(this);
|
||||
tv_version.setText("版本号:V" + BuildConfig.VERSION_NAME);
|
||||
iv_back.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
cl_pic.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
switchContent(0);
|
||||
}
|
||||
});
|
||||
cl_video.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
switchContent(1);
|
||||
}
|
||||
});
|
||||
cl_doc.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
switchContent(2);
|
||||
}
|
||||
});
|
||||
mFragmentManager = getSupportFragmentManager();
|
||||
mFragments = new Fragment[3];
|
||||
switchContent(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initData() {
|
||||
getHomeSpaceInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
checkSelfPermission();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
if (requestCode == REQUEST_PERMISSION_CODE) {
|
||||
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
Log.e("TAG", "onRequestPermissionsResult: ");
|
||||
getThumbnail();
|
||||
} else if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
|
||||
if (ActivityCompat.shouldShowRequestPermissionRationale(LandMainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
|
||||
ToastUtil.show("需要存储空间权限才能正常使用软件");
|
||||
checkSelfPermission();
|
||||
} else {
|
||||
ToastUtil.show("请打开存储空间权限后使用软件");
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
intent.setData(Uri.parse("package:" + this.getPackageName()));
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkSelfPermission() {
|
||||
List<String> mPermissionList = new ArrayList<>();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
for (String s : permissions) {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
|
||||
mPermissionList.add(s);
|
||||
} else {
|
||||
Log.e("TAG", "checkSelfPermission: ");
|
||||
// mPresenter.getHomeVideo();
|
||||
getThumbnail();
|
||||
}
|
||||
}
|
||||
if (mPermissionList.size() > 0) {//有权限没有通过,需要申请
|
||||
ActivityCompat.requestPermissions(this, permissions, REQUEST_PERMISSION_CODE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void getHomeSpaceInfo() {
|
||||
NetInterfaceManager.getInstance().getHomeSpaceInfoControl()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<BaseResponse<SpaceInfo>>() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
Log.e("getHomeSpaceInfo", "onSubscribe: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull BaseResponse<SpaceInfo> spaceInfoBaseResponse) {
|
||||
Log.e("getHomeSpaceInfo", "onNext: " + spaceInfoBaseResponse);
|
||||
if (spaceInfoBaseResponse.code == 200) {
|
||||
SpaceInfo spaceInfo = spaceInfoBaseResponse.data;
|
||||
String home_video_grade = spaceInfo.getHome_video_grade();
|
||||
long quota = spaceInfo.getQuota();
|
||||
long use_quota = spaceInfo.getUse_quota();
|
||||
tv_rank.setText(home_video_grade);
|
||||
tv_space.setText(Utils.formatFileSize(use_quota) + "/" + Utils.formatFileSize(quota));
|
||||
} else {
|
||||
tv_rank.setText("普通");
|
||||
tv_space.setText("0GB/0GB");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
Log.e("getHomeSpaceInfo", "onError: " + e.getMessage());
|
||||
onComplete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Log.e("getHomeSpaceInfo", "onComplete: ");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 切换显示内容
|
||||
public void switchContent(int index) {
|
||||
switchPic(index);
|
||||
FragmentTransaction transaction = mFragmentManager.beginTransaction();
|
||||
hideFragments(transaction);
|
||||
try {
|
||||
switch (index) {
|
||||
case 0:
|
||||
if (mFragments[0] == null) {
|
||||
mFragments[0] = new PictureFragment();
|
||||
transaction.add(R.id.content, mFragments[0], 0 + "");
|
||||
} else {
|
||||
transaction.show(mFragments[0]);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (mFragments[1] == null) {
|
||||
mFragments[1] = new VideoFragment();
|
||||
transaction.add(R.id.content, mFragments[1], 1 + "");
|
||||
} else {
|
||||
transaction.show(mFragments[1]);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (mFragments[2] == null) {
|
||||
mFragments[2] = new DocFragment();
|
||||
transaction.add(R.id.content, mFragments[2], 2 + "");
|
||||
} else {
|
||||
transaction.show(mFragments[2]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
transaction.commit();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void switchPic(int index) {
|
||||
// iv_pic.setImageDrawable(getDrawable(R.drawable.home_icon_picture_normal));
|
||||
// iv_video.setImageDrawable(getDrawable(R.drawable.home_icon_video_normal));
|
||||
// iv_doc.setImageDrawable(getDrawable(R.drawable.home_icon_doc_normal));
|
||||
// Animation animation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.anim_small);
|
||||
cl_pic.setBackground(null);
|
||||
cl_video.setBackground(null);
|
||||
cl_doc.setBackground(null);
|
||||
switch (index) {
|
||||
case 0:
|
||||
// iv_pic.startAnimation(animation);
|
||||
iv_pic.setImageDrawable(getDrawable(R.drawable.home_icon_picture_pressed));
|
||||
iv_video.setImageDrawable(getDrawable(R.drawable.home_icon_video_normal));
|
||||
cl_pic.setBackground(getDrawable(R.drawable.alarm_pressed_background));
|
||||
break;
|
||||
case 1:
|
||||
// iv_video.startAnimation(animation);
|
||||
iv_pic.setImageDrawable(getDrawable(R.drawable.home_icon_picture_normal));
|
||||
iv_video.setImageDrawable(getDrawable(R.drawable.home_icon_video_pressed));
|
||||
cl_video.setBackground(getDrawable(R.drawable.alarm_pressed_background));
|
||||
break;
|
||||
case 2:
|
||||
// iv_doc.startAnimation(animation);
|
||||
// iv_doc.setImageDrawable(getDrawable(R.drawable.home_icon_doc_checked));
|
||||
cl_doc.setBackground(getDrawable(R.drawable.alarm_pressed_background));
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
// 将所有的Fragment都置为隐藏状态。
|
||||
private void hideFragments(FragmentTransaction transaction) {
|
||||
if (mFragments != null) {
|
||||
for (Fragment fragment : mFragments) {
|
||||
if (fragment != null) {
|
||||
transaction.hide(fragment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void getThumbnail() {
|
||||
long s1 = System.currentTimeMillis();
|
||||
List<String> picFileList = new ArrayList<>();
|
||||
List<String> videoFileList = new ArrayList<>();
|
||||
String rootPath = JGYUtils.getInstance().getDownLoadPath() + File.separator;
|
||||
File file = new File(rootPath);
|
||||
if (file.exists()) {
|
||||
LinkedList<File> list = new LinkedList<File>();
|
||||
File[] files = file.listFiles();
|
||||
if (files == null) {
|
||||
return;
|
||||
}
|
||||
for (File file2 : files) {
|
||||
if (file2.isDirectory()) {
|
||||
list.add(file2);
|
||||
} else {
|
||||
if (VideoUtils.isPicFormat(file2.getAbsolutePath())) {
|
||||
picFileList.add(file2.getAbsolutePath());
|
||||
} else if (VideoUtils.isVideoFormat(file2.getAbsolutePath())) {
|
||||
videoFileList.add(file2.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
File temp_file;
|
||||
while (!list.isEmpty()) {
|
||||
temp_file = list.removeFirst();
|
||||
files = temp_file.listFiles();
|
||||
if (files == null) {
|
||||
continue;
|
||||
}
|
||||
for (File file2 : files) {
|
||||
if (file2.isDirectory()) {
|
||||
list.add(file2);
|
||||
} else {
|
||||
if (VideoUtils.isPicFormat(file2.getAbsolutePath())) {
|
||||
picFileList.add(file2.getAbsolutePath());
|
||||
} else if (VideoUtils.isVideoFormat(file2.getAbsolutePath())) {
|
||||
videoFileList.add(file2.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.e("traverseFolder1", "文件不存在!");
|
||||
}
|
||||
Log.e("ScanTask", "doInBackground: " + "Scan time = " + (System.currentTimeMillis() - s1) + "ms");
|
||||
Log.e("getThumbnail", "picFileList: " + picFileList);
|
||||
Log.e("getThumbnail", "videoFileList: " + videoFileList);
|
||||
Log.e("getThumbnail", "picFileList size = " + picFileList.size());
|
||||
Log.e("getThumbnail", "videoFileList size = " + videoFileList.size());
|
||||
// if (picFileList.size() == 0) {
|
||||
// nv_pic.setImageDrawable(getDrawable(R.drawable.icon_pic));
|
||||
// } else {
|
||||
// nv_pic.setImageDrawable(path2Drawable(picFileList.get(0)));
|
||||
// }
|
||||
// if (videoFileList.size() == 0) {
|
||||
// nv_video.setImageDrawable(getDrawable(R.drawable.icon_video));
|
||||
// } else {
|
||||
// Observable.create(new ObservableOnSubscribe<Bitmap>() {
|
||||
// @Override
|
||||
// public void subscribe(ObservableEmitter<Bitmap> emitter) throws Exception {
|
||||
// FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
|
||||
// mmr.setDataSource(videoFileList.get(0));
|
||||
// Bitmap bitmap = mmr.getFrameAtTime();//获得视频第一帧的Bitmap对象.
|
||||
// mmr.release();
|
||||
// emitter.onNext(bitmap);
|
||||
// }
|
||||
// }).subscribeOn(Schedulers.newThread())
|
||||
// .observeOn(AndroidSchedulers.mainThread())
|
||||
// .subscribe(new Observer<Bitmap>() {
|
||||
// @Override
|
||||
// public void onSubscribe(Disposable d) {
|
||||
// Log.e("VideoResult", "onSubscribe: ");
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onNext(Bitmap result) {
|
||||
// Log.e("VideoResult", "onNext: " + result);
|
||||
// nv_video.setImageBitmap(result);
|
||||
//// Glide.with(nv_video).load(result).error(R.drawable.icon_video).into(nv_video);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onError(Throwable e) {
|
||||
// Log.e("VideoResult", "onError: " + e.getMessage());
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onComplete() {
|
||||
// Log.e("VideoResult", "onComplete: ");
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
Log.e("getThumbnail", "videoFileList size = " + videoFileList.size());
|
||||
// CombineBitmap.init(this)
|
||||
// .setLayoutManager(new DingLayoutManager()) // 必选, 设置图片的组合形式,支持WechatLayoutManager、DingLayoutManager
|
||||
// .setSize(100) // 必选,组合后Bitmap的尺寸,单位dp
|
||||
// .setGap(1) // 单个图片之间的距离,单位dp,默认0dp
|
||||
//// .setGapColor() // 单个图片间距的颜色,默认白色
|
||||
//// .setPlaceholder() // 单个图片加载失败的默认显示图片
|
||||
// .setUrls(picFileList.toArray(new String[picFileList.size()])) // 要加载的图片url数组
|
||||
// .setBitmaps() // 要加载的图片bitmap数组
|
||||
// .setResourceIds() // 要加载的图片资源id数组
|
||||
// .setImageView(nv_pic) // 直接设置要显示图片的ImageView
|
||||
// // 设置“子图片”的点击事件,需使用setImageView(),index和图片资源数组的索引对应
|
||||
//// .setOnSubItemClickListener(new OnSubItemClickListener() {
|
||||
//// @Override
|
||||
//// public void onSubItemClick(int index) {
|
||||
////
|
||||
//// }
|
||||
//// })
|
||||
//// // 加载进度的回调函数,如果不使用setImageView()方法,可在onComplete()完成最终图片的显示
|
||||
//// .setProgressListener(new ProgressListener() {
|
||||
//// @Override
|
||||
//// public void onStart() {
|
||||
////
|
||||
//// }
|
||||
////
|
||||
//// @Override
|
||||
//// public void onComplete(Bitmap bitmap) {
|
||||
////
|
||||
//// }
|
||||
//// })
|
||||
// .build();
|
||||
|
||||
// CombineBitmap.init(this)
|
||||
// .setLayoutManager(new DingLayoutManager()) // 必选, 设置图片的组合形式,支持WechatLayoutManager、DingLayoutManager
|
||||
// .setSize(100) // 必选,组合后Bitmap的尺寸,单位dp
|
||||
// .setGap(1) // 单个图片之间的距离,单位dp,默认0dp
|
||||
//// .setGapColor() // 单个图片间距的颜色,默认白色
|
||||
//// .setPlaceholder() // 单个图片加载失败的默认显示图片
|
||||
// .setUrls(videoFileList.toArray(new String[videoFileList.size()])) // 要加载的图片url数组
|
||||
// .setBitmaps() // 要加载的图片bitmap数组
|
||||
// .setResourceIds() // 要加载的图片资源id数组
|
||||
// .setImageView(nv_video) // 直接设置要显示图片的ImageView
|
||||
// .build();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将本地图片转换为 Drawable
|
||||
*
|
||||
* @param file 文件路径
|
||||
* @return
|
||||
*/
|
||||
public Drawable path2Drawable(String file) {
|
||||
if (file == null || file.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Drawable drawable = null;
|
||||
try {
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
Bitmap bitmap = BitmapFactory.decodeStream(fis);
|
||||
drawable = new BitmapDrawable(getResources(), bitmap);
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return drawable;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,27 @@
|
||||
package com.uiui.videoplayer.activity.pic;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.uiui.videoplayer.R;
|
||||
import com.uiui.videoplayer.adapter.PicAdapter;
|
||||
import com.uiui.videoplayer.base.BGAGridDivider;
|
||||
import com.uiui.videoplayer.base.BaseLightActivity;
|
||||
import com.uiui.videoplayer.base.GridSpaceItemDecoration;
|
||||
import com.uiui.videoplayer.base.BaseActivity;
|
||||
import com.uiui.videoplayer.bean.PhotoInfo;
|
||||
import com.uiui.videoplayer.utils.ToastUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
public class GalleryActivity extends BaseLightActivity implements GalleryContact.GalleryView {
|
||||
public class GalleryActivity extends BaseActivity implements GalleryContact.GalleryView {
|
||||
|
||||
@BindView(R.id.swipeRefreshLayout)
|
||||
SwipeRefreshLayout swipeRefreshLayout;
|
||||
@@ -47,11 +43,16 @@ public class GalleryActivity extends BaseLightActivity implements GalleryContact
|
||||
return R.layout.activity_gallery;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean setNightMode() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initView() {
|
||||
ButterKnife.bind(this);
|
||||
mPresenter = new GalleryPresenter(this);
|
||||
mPresenter.setLifecycle(lifecycleSubject);
|
||||
mPresenter.setLifecycle(getLifecycleSubject());
|
||||
mPresenter.attachView(this);
|
||||
|
||||
GridLayoutManager layoutManager = new GridLayoutManager(this, SPAN_COUNT, LinearLayoutManager.VERTICAL, false);
|
||||
|
||||
@@ -10,7 +10,7 @@ import androidx.viewpager.widget.ViewPager;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.uiui.videoplayer.R;
|
||||
import com.uiui.videoplayer.adapter.PreviewAdapter;
|
||||
import com.uiui.videoplayer.base.BaseLightActivity;
|
||||
import com.uiui.videoplayer.base.BaseActivity;
|
||||
import com.uiui.videoplayer.base.ScaleCircleNavigator;
|
||||
import com.uiui.videoplayer.bean.PhotoInfo;
|
||||
import com.zackratos.ultimatebarx.ultimatebarx.java.UltimateBarX;
|
||||
@@ -24,7 +24,7 @@ import java.util.List;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
public class PreviewActivity extends BaseLightActivity {
|
||||
public class PreviewActivity extends BaseActivity {
|
||||
|
||||
@BindView(R.id.viewPager)
|
||||
ViewPager viewPager;
|
||||
@@ -40,6 +40,11 @@ public class PreviewActivity extends BaseLightActivity {
|
||||
return R.layout.activity_preview;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean setNightMode() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initView() {
|
||||
UltimateBarX.statusBar(this)
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
package com.uiui.videoplayer.activity.video;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
@@ -23,7 +18,6 @@ import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
@@ -36,10 +30,9 @@ import com.arialyy.aria.core.task.DownloadTask;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.uiui.videoplayer.R;
|
||||
import com.uiui.videoplayer.adapter.VideoAdapter;
|
||||
import com.uiui.videoplayer.base.BaseLightActivity;
|
||||
import com.uiui.videoplayer.base.BaseActivity;
|
||||
import com.uiui.videoplayer.base.CustomDialog;
|
||||
import com.uiui.videoplayer.base.RecycleGridLayoutManager;
|
||||
import com.uiui.videoplayer.base.SpacesItemDecoration;
|
||||
import com.uiui.videoplayer.bean.LocalVideoInfo;
|
||||
import com.uiui.videoplayer.gson.GsonUtils;
|
||||
import com.uiui.videoplayer.utils.SPUtils;
|
||||
@@ -54,7 +47,7 @@ import java.util.List;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
public class VideoActivity extends BaseLightActivity implements VideoContact.VideoView {
|
||||
public class VideoActivity extends BaseActivity implements VideoContact.VideoView {
|
||||
|
||||
private static final String TAG = VideoActivity.class.getSimpleName();
|
||||
|
||||
@@ -80,7 +73,7 @@ public class VideoActivity extends BaseLightActivity implements VideoContact.Vid
|
||||
public void initView() {
|
||||
ButterKnife.bind(this);
|
||||
mPresenter = new VideoPresenter(this);
|
||||
mPresenter.setLifecycle(lifecycleSubject);
|
||||
mPresenter.setLifecycle(getLifecycleSubject());
|
||||
mPresenter.attachView(this);
|
||||
|
||||
Aria.download(this).register();
|
||||
@@ -101,8 +94,7 @@ public class VideoActivity extends BaseLightActivity implements VideoContact.Vid
|
||||
}
|
||||
recyclerView.setLayoutManager(mManager);
|
||||
recyclerView.setNestedScrollingEnabled(false);
|
||||
recyclerView.addItemDecoration(new SpacesItemDecoration(getResources().getDimensionPixelSize(R.dimen.PX1x), getResources().getDimensionPixelSize(R.dimen.PX1x),
|
||||
getResources().getDimensionPixelSize(R.dimen.PX1x), getResources().getDimensionPixelSize(R.dimen.PX1x)));
|
||||
|
||||
((DefaultItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
|
||||
adapter = new VideoAdapter(VideoActivity.this);
|
||||
adapter.setOnLongClickListener(new VideoAdapter.onItemLongClickListener() {
|
||||
@@ -141,6 +133,11 @@ public class VideoActivity extends BaseLightActivity implements VideoContact.Vid
|
||||
return R.layout.activity_video;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean setNightMode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.uiui.videoplayer.activity.vip;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import androidx.lifecycle.Observer;
|
||||
|
||||
import com.uiui.videoplayer.R;
|
||||
import com.uiui.videoplayer.base.mvvm.BaseMvvmActivity;
|
||||
import com.uiui.videoplayer.bean.SpaceInfo;
|
||||
import com.uiui.videoplayer.databinding.ActivityVipBinding;
|
||||
import com.uiui.videoplayer.utils.Utils;
|
||||
|
||||
public class VipActivity extends BaseMvvmActivity<VipViewModel, ActivityVipBinding> {
|
||||
|
||||
|
||||
/**
|
||||
* 设置布局
|
||||
*/
|
||||
@Override
|
||||
protected int getLayoutId() {
|
||||
return R.layout.activity_vip;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 是否是黑色状态栏
|
||||
*/
|
||||
@Override
|
||||
protected boolean setNightMode() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initDataBinding() {
|
||||
mViewModel.setCtx(this);
|
||||
mViewModel.setVDBinding(mViewDataBinding);
|
||||
mViewModel.setLifecycle(getLifecycleSubject());
|
||||
mViewDataBinding.setClick(new Click());
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化视图
|
||||
*/
|
||||
@Override
|
||||
protected void initView() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
@Override
|
||||
protected void initData() {
|
||||
mViewModel.getSpaceInfoData().observe(this, new Observer<SpaceInfo>() {
|
||||
@Override
|
||||
public void onChanged(SpaceInfo spaceInfo) {
|
||||
if (spaceInfo == null) {
|
||||
// tv_rank.setText("普通");
|
||||
mViewDataBinding.tvSpaceFree.setText("0GB/0GB");
|
||||
mViewDataBinding.tvSpaceUsed.setText("0%");
|
||||
|
||||
} else {
|
||||
String home_video_grade = spaceInfo.getHome_video_grade();
|
||||
long quota = spaceInfo.getQuota();
|
||||
long use_quota = spaceInfo.getUse_quota();
|
||||
// tv_rank.setText(home_video_grade);
|
||||
mViewDataBinding.tvSpaceFree.setText(String.format(getString(R.string.space_free), Utils.formatFileSize(use_quota), Utils.formatFileSize(quota)));
|
||||
int percentage = (int) ((quota - use_quota) * 100 / (float) quota);
|
||||
mViewDataBinding.tvSpaceUsed.setText(String.format(getString(R.string.space_used), (percentage + "%")));
|
||||
}
|
||||
}
|
||||
});
|
||||
mViewModel.getHomeSpaceInfo();
|
||||
|
||||
}
|
||||
|
||||
public class Click {
|
||||
public void exit(View view) {
|
||||
finish();
|
||||
}
|
||||
|
||||
public void empty(View view) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.uiui.videoplayer.activity.vip;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.trello.rxlifecycle4.RxLifecycle;
|
||||
import com.trello.rxlifecycle4.android.ActivityEvent;
|
||||
import com.uiui.videoplayer.base.mvvm.BaseViewModel;
|
||||
import com.uiui.videoplayer.bean.BaseResponse;
|
||||
import com.uiui.videoplayer.bean.SpaceInfo;
|
||||
import com.uiui.videoplayer.databinding.ActivityVipBinding;
|
||||
import com.uiui.videoplayer.network.NetInterfaceManager;
|
||||
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.rxjava3.annotations.NonNull;
|
||||
import io.reactivex.rxjava3.core.Observer;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
|
||||
public class VipViewModel extends BaseViewModel<ActivityVipBinding> {
|
||||
@Override
|
||||
public ActivityVipBinding getVDBinding() {
|
||||
return binding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
|
||||
}
|
||||
|
||||
private MutableLiveData<SpaceInfo> mSpaceInfoData = new MutableLiveData<>();
|
||||
|
||||
public MutableLiveData<SpaceInfo> getSpaceInfoData() {
|
||||
return mSpaceInfoData;
|
||||
}
|
||||
|
||||
public void getHomeSpaceInfo() {
|
||||
NetInterfaceManager.getInstance().getHomeSpaceInfoControl()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
|
||||
.subscribe(new Observer<BaseResponse<SpaceInfo>>() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
Log.e("getHomeSpaceInfo", "onSubscribe: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull BaseResponse<SpaceInfo> spaceInfoBaseResponse) {
|
||||
Log.e("getHomeSpaceInfo", "onNext: " + spaceInfoBaseResponse);
|
||||
if (spaceInfoBaseResponse.code == 200) {
|
||||
SpaceInfo spaceInfo = spaceInfoBaseResponse.data;
|
||||
mSpaceInfoData.setValue(spaceInfo);
|
||||
} else {
|
||||
mSpaceInfoData.setValue(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
Log.e("getHomeSpaceInfo", "onError: " + e.getMessage());
|
||||
onComplete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Log.e("getHomeSpaceInfo", "onComplete: ");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.uiui.videoplayer.adapter;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public class EquallyDividedItemDecoration extends RecyclerView.ItemDecoration {
|
||||
private static final String TAG = EquallyDividedItemDecoration.class.getSimpleName();
|
||||
|
||||
private int mSpanCount;//横条目数量
|
||||
private int mHalfRowSpacing;//行间距的一半
|
||||
private int mHalfColumnSpacing;// 列间距的一半
|
||||
|
||||
|
||||
public EquallyDividedItemDecoration(int spanCount, int halfRowSpacing) {
|
||||
mSpanCount = spanCount;
|
||||
mHalfRowSpacing = halfRowSpacing;
|
||||
mHalfColumnSpacing = halfRowSpacing;
|
||||
}
|
||||
|
||||
public EquallyDividedItemDecoration(int spanCount, int halfRowSpacing, int halfColumnSpacing) {
|
||||
mSpanCount = spanCount;
|
||||
mHalfRowSpacing = halfRowSpacing;
|
||||
mHalfColumnSpacing = halfColumnSpacing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
|
||||
super.getItemOffsets(outRect, view, parent, state);
|
||||
int position = parent.getChildAdapterPosition(view); // 获取view 在adapter中的位置。
|
||||
Log.d(TAG, "getItemOffsets: position = " + position);
|
||||
|
||||
int itemCount = parent.getAdapter().getItemCount();//item全部数量
|
||||
Log.d(TAG, "getItemOffsets: itemCount = " + itemCount);
|
||||
|
||||
int column = position % mSpanCount; // view 所在的列
|
||||
Log.d(TAG, "getItemOffsets: column = " + column);
|
||||
|
||||
if (column == 0) {
|
||||
outRect.left = 2 * mHalfRowSpacing;
|
||||
outRect.right = mHalfRowSpacing;
|
||||
} else if (column == mSpanCount - 1) {
|
||||
outRect.left = mHalfRowSpacing;
|
||||
outRect.right = 2 * mHalfRowSpacing;
|
||||
} else {
|
||||
outRect.left = mHalfRowSpacing;
|
||||
outRect.right = mHalfRowSpacing;
|
||||
}
|
||||
|
||||
int row = (position / 3);//所在行
|
||||
Log.d(TAG, "getItemOffsets: row = " + row);
|
||||
int maxRow = (int) Math.ceil((double) itemCount / mSpanCount);//一共多少行
|
||||
Log.d(TAG, "getItemOffsets: maxRow = " + maxRow);
|
||||
|
||||
if (row == 0) {
|
||||
outRect.top = 2 * mHalfColumnSpacing;
|
||||
outRect.bottom = mHalfColumnSpacing;
|
||||
} else if (row == maxRow - 1) {
|
||||
outRect.top = mHalfColumnSpacing;
|
||||
outRect.bottom = 2 * mHalfColumnSpacing;
|
||||
} else {
|
||||
outRect.top = mHalfColumnSpacing;
|
||||
outRect.bottom = mHalfColumnSpacing;
|
||||
}
|
||||
|
||||
Log.d(TAG, "getItemOffsets: outRect.left = " + outRect.left);
|
||||
Log.d(TAG, "getItemOffsets: outRect.right = " + outRect.right);
|
||||
Log.d(TAG, "getItemOffsets: outRect.top = " + outRect.top);
|
||||
Log.d(TAG, "getItemOffsets: outRect.bottom = " + outRect.bottom);
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package com.uiui.videoplayer.adapter;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class RecyclerViewSpacesItemDecoration extends RecyclerView.ItemDecoration {
|
||||
|
||||
private final HashMap<String, Integer> mSpaceValueMap;
|
||||
|
||||
public static final String TOP_DECORATION = "top_decoration";
|
||||
public static final String BOTTOM_DECORATION = "bottom_decoration";
|
||||
public static final String LEFT_DECORATION = "left_decoration";
|
||||
public static final String RIGHT_DECORATION = "right_decoration";
|
||||
|
||||
public RecyclerViewSpacesItemDecoration(final HashMap<String, Integer> mSpaceValueMap) {
|
||||
this.mSpaceValueMap = mSpaceValueMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getItemOffsets(final Rect outRect, final View view, final RecyclerView parent,
|
||||
final RecyclerView.State state) {
|
||||
if (mSpaceValueMap.get(TOP_DECORATION) != null) {
|
||||
outRect.top = mSpaceValueMap.get(TOP_DECORATION);
|
||||
}
|
||||
if (mSpaceValueMap.get(LEFT_DECORATION) != null) {
|
||||
outRect.left = mSpaceValueMap.get(LEFT_DECORATION);
|
||||
}
|
||||
if (mSpaceValueMap.get(RIGHT_DECORATION) != null) {
|
||||
outRect.right = mSpaceValueMap.get(RIGHT_DECORATION);
|
||||
}
|
||||
if (mSpaceValueMap.get(BOTTOM_DECORATION) != null) {
|
||||
outRect.bottom = mSpaceValueMap.get(BOTTOM_DECORATION);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,134 +1,32 @@
|
||||
package com.uiui.videoplayer.base;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.CallSuper;
|
||||
import androidx.annotation.CheckResult;
|
||||
import androidx.annotation.ContentView;
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.trello.rxlifecycle4.LifecycleProvider;
|
||||
import com.trello.rxlifecycle4.LifecycleTransformer;
|
||||
import com.trello.rxlifecycle4.RxLifecycle;
|
||||
import com.trello.rxlifecycle4.android.ActivityEvent;
|
||||
import com.trello.rxlifecycle4.android.RxLifecycleAndroid;
|
||||
import com.uiui.videoplayer.R;
|
||||
import com.zackratos.ultimatebarx.ultimatebarx.java.UltimateBarX;
|
||||
|
||||
import io.reactivex.rxjava3.core.Observable;
|
||||
import io.reactivex.rxjava3.subjects.BehaviorSubject;
|
||||
|
||||
|
||||
public abstract class BaseActivity extends AppCompatActivity implements LifecycleProvider<ActivityEvent> {
|
||||
public final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
// StatusBarUtil.init(this);
|
||||
UltimateBarX.statusBar(this)
|
||||
.transparent()
|
||||
.colorRes(R.color.colorPrimaryDark)
|
||||
.light(true)
|
||||
.apply();
|
||||
UltimateBarX.navigationBar(this)
|
||||
.transparent()
|
||||
.colorRes(R.color.colorPrimaryDark)
|
||||
.light(true)
|
||||
.apply();
|
||||
setContentView(this.getLayoutId());
|
||||
initView();
|
||||
initData();
|
||||
//最近任务和应用图标不一样
|
||||
// if (Build.VERSION.SDK_INT > 27) {
|
||||
// ActivityManager.TaskDescription description = new ActivityManager.TaskDescription(getString(R.string.app_name), R.mipmap.ic_launcher, getColor(R.color.colorPrimary));
|
||||
// this.setTaskDescription(description);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置布局
|
||||
*/
|
||||
public abstract int getLayoutId();
|
||||
|
||||
/**
|
||||
* 初始化视图
|
||||
*/
|
||||
public abstract void initView();
|
||||
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
public abstract void initData();
|
||||
public abstract class BaseActivity extends BaseTransparentActivity {
|
||||
|
||||
public BaseActivity() {
|
||||
super();
|
||||
}
|
||||
|
||||
@ContentView
|
||||
public BaseActivity(@LayoutRes int contentLayoutId) {
|
||||
super(contentLayoutId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
@CheckResult
|
||||
public final Observable<ActivityEvent> lifecycle() {
|
||||
return lifecycleSubject.hide();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
@CheckResult
|
||||
public final <T> LifecycleTransformer<T> bindUntilEvent(@NonNull ActivityEvent event) {
|
||||
return RxLifecycle.bindUntilEvent(lifecycleSubject, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
@CheckResult
|
||||
public final <T> LifecycleTransformer<T> bindToLifecycle() {
|
||||
return RxLifecycleAndroid.bindActivity(lifecycleSubject);
|
||||
}
|
||||
|
||||
@Override
|
||||
@CallSuper
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
lifecycleSubject.onNext(ActivityEvent.START);
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(getLayoutId());
|
||||
initView();
|
||||
initData();
|
||||
}
|
||||
|
||||
@Override
|
||||
@CallSuper
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
lifecycleSubject.onNext(ActivityEvent.RESUME);
|
||||
}
|
||||
/**
|
||||
* 初始化视图
|
||||
*/
|
||||
protected abstract void initView();
|
||||
|
||||
@Override
|
||||
@CallSuper
|
||||
protected void onPause() {
|
||||
lifecycleSubject.onNext(ActivityEvent.PAUSE);
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
@CallSuper
|
||||
protected void onStop() {
|
||||
lifecycleSubject.onNext(ActivityEvent.STOP);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
@CallSuper
|
||||
protected void onDestroy() {
|
||||
lifecycleSubject.onNext(ActivityEvent.DESTROY);
|
||||
super.onDestroy();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
protected abstract void initData();
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.uiui.videoplayer.base;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.CallSuper;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public abstract class BaseDataBindingActivity extends BaseTransparentActivity {
|
||||
|
||||
public BaseDataBindingActivity() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
@CallSuper
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
initView();
|
||||
initData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化视图
|
||||
*/
|
||||
protected abstract void initView();
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
protected abstract void initData();
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
package com.uiui.videoplayer.base;
|
||||
|
||||
import android.util.SparseArray;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentPagerAdapter;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 加载显示Fragment的ViewPagerAdapter基类
|
||||
* 提供可以刷新的方法
|
||||
*
|
||||
* @author Fly
|
||||
* @e-mail 1285760616@qq.com
|
||||
* @time 2018/3/22
|
||||
*/
|
||||
public class BaseFragmentPagerAdapter extends FragmentPagerAdapter {
|
||||
private List<Fragment> mFragmentList;
|
||||
private FragmentManager mFragmentManager;
|
||||
/**下面两个值用来保存Fragment的位置信息,用以判断该位置是否需要更新*/
|
||||
private SparseArray<String> mFragmentPositionMap;
|
||||
private SparseArray<String> mFragmentPositionMapAfterUpdate;
|
||||
|
||||
public BaseFragmentPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
|
||||
super(fm);
|
||||
mFragmentList = fragments;
|
||||
mFragmentManager = fm;
|
||||
mFragmentList = fragments;
|
||||
mFragmentPositionMap = new SparseArray<>();
|
||||
mFragmentPositionMapAfterUpdate = new SparseArray<>();
|
||||
setFragmentPositionMap();
|
||||
setFragmentPositionMapForUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存更新之前的位置信息,用<hashCode, position>的键值对结构来保存
|
||||
*/
|
||||
private void setFragmentPositionMap() {
|
||||
mFragmentPositionMap.clear();
|
||||
for (int i = 0; i < mFragmentList.size(); i++) {
|
||||
mFragmentPositionMap.put(Long.valueOf(getItemId(i)).intValue(), String.valueOf(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存更新之后的位置信息,用<hashCode, position>的键值对结构来保存
|
||||
*/
|
||||
private void setFragmentPositionMapForUpdate() {
|
||||
mFragmentPositionMapAfterUpdate.clear();
|
||||
for (int i = 0; i < mFragmentList.size(); i++) {
|
||||
mFragmentPositionMapAfterUpdate.put(Long.valueOf(getItemId(i)).intValue(), String.valueOf(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 在此方法中找到需要更新的位置返回POSITION_NONE,否则返回POSITION_UNCHANGED即可
|
||||
*/
|
||||
@Override
|
||||
public int getItemPosition(Object object) {
|
||||
int hashCode = object.hashCode();
|
||||
//查找object在更新后的列表中的位置
|
||||
String position = mFragmentPositionMapAfterUpdate.get(hashCode);
|
||||
//更新后的列表中不存在该object的位置了
|
||||
if (position == null) {
|
||||
return POSITION_NONE;
|
||||
} else {
|
||||
//如果更新后的列表中存在该object的位置, 查找该object之前的位置并判断位置是否发生了变化
|
||||
int size = mFragmentPositionMap.size();
|
||||
for (int i = 0; i < size ; i++) {
|
||||
int key = mFragmentPositionMap.keyAt(i);
|
||||
if (key == hashCode) {
|
||||
String index = mFragmentPositionMap.get(key);
|
||||
if (position.equals(index)) {
|
||||
//位置没变依然返回POSITION_UNCHANGED
|
||||
return POSITION_UNCHANGED;
|
||||
} else {
|
||||
//位置变了
|
||||
return POSITION_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return POSITION_UNCHANGED;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将指定的Fragment替换/更新为新的Fragment
|
||||
* @param oldFragment 旧Fragment
|
||||
* @param newFragment 新Fragment
|
||||
*/
|
||||
public void replaceFragment(Fragment oldFragment, Fragment newFragment) {
|
||||
int position = mFragmentList.indexOf(oldFragment);
|
||||
if (position == -1) {
|
||||
return;
|
||||
}
|
||||
//从Transaction移除旧的Fragment
|
||||
removeFragmentInternal(oldFragment);
|
||||
//替换List中对应的Fragment
|
||||
mFragmentList.set(position, newFragment);
|
||||
//刷新Adapter
|
||||
notifyItemChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将指定位置的Fragment替换/更新为新的Fragment,同{@link #replaceFragment(Fragment oldFragment, Fragment newFragment)}
|
||||
* @param position 旧Fragment的位置
|
||||
* @param newFragment 新Fragment
|
||||
*/
|
||||
public void replaceFragment(int position, Fragment newFragment) {
|
||||
Fragment oldFragment = mFragmentList.get(position);
|
||||
removeFragmentInternal(oldFragment);
|
||||
mFragmentList.set(position, newFragment);
|
||||
notifyItemChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除指定的Fragment
|
||||
* @param fragment 目标Fragment
|
||||
*/
|
||||
public void removeFragment(Fragment fragment) {
|
||||
//先从List中移除
|
||||
mFragmentList.remove(fragment);
|
||||
//然后从Transaction移除
|
||||
removeFragmentInternal(fragment);
|
||||
//最后刷新Adapter
|
||||
notifyItemChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除指定位置的Fragment,同 {@link #removeFragment(Fragment fragment)}
|
||||
* @param position
|
||||
*/
|
||||
public void removeFragment(int position) {
|
||||
Fragment fragment = mFragmentList.get(position);
|
||||
//然后从List中移除
|
||||
mFragmentList.remove(fragment);
|
||||
//先从Transaction移除
|
||||
removeFragmentInternal(fragment);
|
||||
//最后刷新Adapter
|
||||
notifyItemChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加Fragment
|
||||
* @param fragment 目标Fragment
|
||||
*/
|
||||
public void addFragment(Fragment fragment) {
|
||||
mFragmentList.add(fragment);
|
||||
notifyItemChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 在指定位置插入一个Fragment
|
||||
* @param position 插入位置
|
||||
* @param fragment 目标Fragment
|
||||
*/
|
||||
public void insertFragment(int position, Fragment fragment) {
|
||||
mFragmentList.add(position, fragment);
|
||||
notifyItemChanged();
|
||||
}
|
||||
|
||||
public void notifyItemChanged() {
|
||||
//刷新之前重新收集位置信息
|
||||
setFragmentPositionMapForUpdate();
|
||||
notifyDataSetChanged();
|
||||
setFragmentPositionMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从Transaction移除Fragment
|
||||
* @param fragment 目标Fragment
|
||||
*/
|
||||
private void removeFragmentInternal(Fragment fragment) {
|
||||
FragmentTransaction transaction = mFragmentManager.beginTransaction();
|
||||
transaction.remove(fragment);
|
||||
transaction.commitAllowingStateLoss();
|
||||
}
|
||||
|
||||
/**
|
||||
* 此方法不用position做返回值即可破解fragment tag异常的错误
|
||||
*/
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
// 获取当前数据的hashCode,其实这里不用hashCode用自定义的可以关联当前Item对象的唯一值也可以,只要不是直接返回position
|
||||
return mFragmentList.get(position).hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
return mFragmentList.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mFragmentList.size();
|
||||
}
|
||||
|
||||
public List<Fragment> getFragments() {
|
||||
return mFragmentList;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
package com.uiui.videoplayer.base;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.CallSuper;
|
||||
import androidx.annotation.CheckResult;
|
||||
import androidx.annotation.ContentView;
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
@@ -16,23 +13,19 @@ import com.trello.rxlifecycle4.LifecycleTransformer;
|
||||
import com.trello.rxlifecycle4.RxLifecycle;
|
||||
import com.trello.rxlifecycle4.android.ActivityEvent;
|
||||
import com.trello.rxlifecycle4.android.RxLifecycleAndroid;
|
||||
import com.uiui.videoplayer.R;
|
||||
import com.zackratos.ultimatebarx.ultimatebarx.java.UltimateBarX;
|
||||
|
||||
import io.reactivex.rxjava3.core.Observable;
|
||||
import io.reactivex.rxjava3.subjects.BehaviorSubject;
|
||||
|
||||
/**
|
||||
* {@link com.trello.rxlifecycle4.components.RxActivity}
|
||||
* copied form RxActivity}
|
||||
*/
|
||||
public abstract class BaseRxActivity extends AppCompatActivity implements LifecycleProvider<ActivityEvent> {
|
||||
private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();
|
||||
|
||||
public abstract class BaseLightActivity extends AppCompatActivity implements LifecycleProvider<ActivityEvent> {
|
||||
public final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();
|
||||
|
||||
public BaseLightActivity() {
|
||||
super();
|
||||
}
|
||||
|
||||
@ContentView
|
||||
public BaseLightActivity(@LayoutRes int contentLayoutId) {
|
||||
super(contentLayoutId);
|
||||
public BehaviorSubject<ActivityEvent> getLifecycleSubject() {
|
||||
return lifecycleSubject;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -61,40 +54,8 @@ public abstract class BaseLightActivity extends AppCompatActivity implements Lif
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
lifecycleSubject.onNext(ActivityEvent.CREATE);
|
||||
// StatusBarUtil.init(this);
|
||||
setContentView(this.getLayoutId());
|
||||
UltimateBarX.statusBar(this)
|
||||
// .transparent()
|
||||
.colorRes(R.color.colorAccent)
|
||||
.fitWindow(true)
|
||||
.light(false)
|
||||
.apply();
|
||||
UltimateBarX.navigationBar(this)
|
||||
.transparent()
|
||||
// .color(Color.TRANSPARENT)
|
||||
.fitWindow(false)
|
||||
.light(false)
|
||||
.apply();
|
||||
initView();
|
||||
initData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置布局
|
||||
*/
|
||||
public abstract int getLayoutId();
|
||||
|
||||
/**
|
||||
* 初始化视图
|
||||
*/
|
||||
public abstract void initView();
|
||||
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
public abstract void initData();
|
||||
|
||||
@Override
|
||||
@CallSuper
|
||||
protected void onStart() {
|
||||
@@ -130,3 +91,4 @@ public abstract class BaseLightActivity extends AppCompatActivity implements Lif
|
||||
super.onDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.uiui.videoplayer.base;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.CallSuper;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.uiui.videoplayer.R;
|
||||
import com.zackratos.ultimatebarx.ultimatebarx.java.UltimateBarX;
|
||||
|
||||
public abstract class BaseTransparentActivity extends BaseRxActivity {
|
||||
|
||||
public BaseTransparentActivity() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
@CallSuper
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
// StatusBarUtil.init(this);
|
||||
UltimateBarX.statusBar(this)
|
||||
.transparent()
|
||||
.colorRes(R.color.colorPrimaryDark)
|
||||
.light(setNightMode())
|
||||
.fitWindow(true)
|
||||
.apply();
|
||||
UltimateBarX.navigationBar(this)
|
||||
.transparent()
|
||||
.colorRes(R.color.colorPrimaryDark)
|
||||
.light(setNightMode())
|
||||
.fitWindow(true)
|
||||
.apply();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置布局
|
||||
*/
|
||||
protected abstract int getLayoutId();
|
||||
|
||||
/**
|
||||
* @return 是否是黑色状态栏
|
||||
*/
|
||||
protected abstract boolean setNightMode();
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.uiui.videoplayer.base.mvvm;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.databinding.DataBindingUtil;
|
||||
import androidx.databinding.ViewDataBinding;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import com.uiui.videoplayer.base.BaseTransparentActivity;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
|
||||
public abstract class BaseMvvmActivity<VM extends ViewModel, VDB extends ViewDataBinding> extends BaseTransparentActivity {
|
||||
|
||||
private static final String TAG = BaseMvvmActivity.class.getSimpleName();
|
||||
|
||||
protected VM mViewModel;
|
||||
protected VDB mViewDataBinding;
|
||||
protected Class<VM> vmClass;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
//ViewDataBinding
|
||||
mViewDataBinding = DataBindingUtil.setContentView(this, getLayoutId());
|
||||
mViewDataBinding.setLifecycleOwner(this);
|
||||
//ViewModel
|
||||
vmClass = (Class<VM>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
|
||||
boolean isAbstract = Modifier.isAbstract(vmClass.getModifiers());
|
||||
Log.e(TAG, "isLocalClass:" + vmClass.getSimpleName().equals(ViewModel.class.getSimpleName()) + " isAbstract:" + isAbstract);
|
||||
if (!isAbstract) {//不是一个抽象类
|
||||
mViewModel = new ViewModelProvider(this).get(vmClass);
|
||||
}
|
||||
initDataBinding();
|
||||
initView();
|
||||
initData();
|
||||
}
|
||||
|
||||
protected abstract void initDataBinding();
|
||||
|
||||
/**
|
||||
* 初始化视图
|
||||
*/
|
||||
protected abstract void initView();
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
protected abstract void initData();
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.uiui.videoplayer.base.mvvm;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.databinding.ViewDataBinding;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
import com.trello.rxlifecycle4.android.ActivityEvent;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import io.reactivex.rxjava3.subjects.BehaviorSubject;
|
||||
|
||||
/**
|
||||
* 所有viewmodel的基类
|
||||
*/
|
||||
public abstract class BaseViewModel<VDB extends ViewDataBinding> extends ViewModel implements ViewDataBindingCallback {
|
||||
|
||||
/**
|
||||
* 当前viewmodel对应的页面binding
|
||||
*/
|
||||
protected VDB binding;
|
||||
|
||||
@Override
|
||||
public void setVDBinding(ViewDataBinding vdBinding) {
|
||||
|
||||
binding = (VDB)vdBinding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VDB getVDBinding() {
|
||||
if (binding == null) {
|
||||
throw new NullPointerException("BaseViewModel >> getVDBinding >> null!!!");
|
||||
}
|
||||
return binding;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 上下文
|
||||
*/
|
||||
private WeakReference<Context> ctx;
|
||||
|
||||
@Override
|
||||
public void setCtx(Context context) {
|
||||
if(ctx == null) {
|
||||
ctx = new WeakReference<>(context);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context getCtx() {
|
||||
if (ctx == null) {
|
||||
throw new NullPointerException("BaseViewModel >> getCtx >> null!!!");
|
||||
}
|
||||
return ctx.get();
|
||||
}
|
||||
|
||||
|
||||
public abstract void onDestroy();
|
||||
|
||||
private BehaviorSubject<ActivityEvent> mBehaviorSubject;
|
||||
|
||||
@Override
|
||||
public void setLifecycle(BehaviorSubject subject) {
|
||||
this.mBehaviorSubject =subject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BehaviorSubject<ActivityEvent> getLifecycle() {
|
||||
return mBehaviorSubject;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.uiui.videoplayer.base.mvvm;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.databinding.ViewDataBinding;
|
||||
|
||||
import com.trello.rxlifecycle4.android.ActivityEvent;
|
||||
|
||||
import io.reactivex.rxjava3.subjects.BehaviorSubject;
|
||||
|
||||
public interface ViewDataBindingCallback<VDB extends ViewDataBinding> {
|
||||
|
||||
|
||||
void setVDBinding(VDB binding);
|
||||
|
||||
VDB getVDBinding() throws NullPointerException;
|
||||
|
||||
|
||||
void setCtx(Context context);
|
||||
|
||||
Context getCtx() throws NullPointerException;
|
||||
|
||||
void setLifecycle(BehaviorSubject<ActivityEvent> subject);
|
||||
|
||||
BehaviorSubject<ActivityEvent> getLifecycle();
|
||||
}
|
||||
@@ -17,15 +17,13 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.uiui.videoplayer.R;
|
||||
import com.uiui.videoplayer.activity.pic.GalleryPresenter;
|
||||
import com.uiui.videoplayer.adapter.EquallyDividedItemDecoration;
|
||||
import com.uiui.videoplayer.adapter.PicAdapter;
|
||||
import com.uiui.videoplayer.adapter.RecyclerViewSpacesItemDecoration;
|
||||
import com.uiui.videoplayer.base.BGAGridDivider;
|
||||
import com.uiui.videoplayer.base.BaseFragment;
|
||||
import com.uiui.videoplayer.bean.PhotoInfo;
|
||||
import com.uiui.videoplayer.utils.ScreenUtils;
|
||||
import com.uiui.videoplayer.utils.ToastUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -127,20 +125,12 @@ public class PictureFragment extends BaseFragment implements PictureContact.Pict
|
||||
mPresenter.attachView(this);
|
||||
|
||||
GridLayoutManager layoutManager = new GridLayoutManager(mContext, SPAN_COUNT, LinearLayoutManager.VERTICAL, false);
|
||||
HashMap<String, Integer> stringIntegerHashMap = new HashMap<>();
|
||||
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
|
||||
DisplayMetrics dm = new DisplayMetrics();
|
||||
wm.getDefaultDisplay().getRealMetrics(dm);
|
||||
float density = dm.density; // 屏幕密度(0.75 / 1.0 / 1.5)
|
||||
stringIntegerHashMap.put(RecyclerViewSpacesItemDecoration.TOP_DECORATION, (int) (density * 1));//top间距
|
||||
stringIntegerHashMap.put(RecyclerViewSpacesItemDecoration.BOTTOM_DECORATION, (int) (density * 1));//底部间距
|
||||
stringIntegerHashMap.put(RecyclerViewSpacesItemDecoration.LEFT_DECORATION, (int) (density * 20));//左间距
|
||||
stringIntegerHashMap.put(RecyclerViewSpacesItemDecoration.RIGHT_DECORATION, (int) (density * 20));//右间距
|
||||
recyclerView.addItemDecoration(new RecyclerViewSpacesItemDecoration(stringIntegerHashMap));
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
|
||||
EquallyDividedItemDecoration equallyDividedItemDecoration = new EquallyDividedItemDecoration(SPAN_COUNT, ScreenUtils.dip2px(mContext, 1));
|
||||
recyclerView.addItemDecoration(equallyDividedItemDecoration);
|
||||
|
||||
mPicAdapter = new PicAdapter(layoutManager);
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
recyclerView.addItemDecoration(BGAGridDivider.newInstanceWithSpaceRes(R.dimen.dp_2));
|
||||
recyclerView.setAdapter(mPicAdapter);
|
||||
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
|
||||
@Override
|
||||
|
||||
@@ -1,23 +1,16 @@
|
||||
package com.uiui.videoplayer.fragment.video;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import com.arialyy.annotations.Download;
|
||||
@@ -25,22 +18,19 @@ import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.task.DownloadTask;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.uiui.videoplayer.R;
|
||||
import com.uiui.videoplayer.activity.video.VideoActivity;
|
||||
import com.uiui.videoplayer.adapter.RecyclerViewSpacesItemDecoration;
|
||||
import com.uiui.videoplayer.adapter.EquallyDividedItemDecoration;
|
||||
import com.uiui.videoplayer.adapter.VideoAdapter;
|
||||
import com.uiui.videoplayer.base.BaseFragment;
|
||||
import com.uiui.videoplayer.base.CustomDialog;
|
||||
import com.uiui.videoplayer.base.RecycleGridLayoutManager;
|
||||
import com.uiui.videoplayer.base.SpacesItemDecoration;
|
||||
import com.uiui.videoplayer.bean.LocalVideoInfo;
|
||||
import com.uiui.videoplayer.gson.GsonUtils;
|
||||
import com.uiui.videoplayer.utils.ScreenUtils;
|
||||
import com.uiui.videoplayer.utils.ToastUtil;
|
||||
import com.uiui.videoplayer.utils.VideoUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
@@ -65,8 +55,9 @@ public class VideoFragment extends BaseFragment implements VideoContact.VideoVie
|
||||
|
||||
private VideoPresenter mPresenter;
|
||||
private RecycleGridLayoutManager mManager;
|
||||
private VideoAdapter adapter;
|
||||
|
||||
private VideoAdapter mVideoAdapter;
|
||||
private static final int SPAN_COUNT = 3;
|
||||
|
||||
// TODO: Rename parameter arguments, choose names that match
|
||||
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
|
||||
private static final String ARG_PARAM1 = "param1";
|
||||
@@ -145,38 +136,22 @@ public class VideoFragment extends BaseFragment implements VideoContact.VideoVie
|
||||
refreshLayout.setRefreshing(true);
|
||||
}
|
||||
});
|
||||
// ((SimpleItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
|
||||
// int orientation = getResources().getConfiguration().orientation;
|
||||
// if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
// mManager = new RecycleGridLayoutManager(mContext, 4);
|
||||
// } else if (orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
mManager = new RecycleGridLayoutManager(mContext, 3);
|
||||
// }
|
||||
|
||||
HashMap<String, Integer> stringIntegerHashMap = new HashMap<>();
|
||||
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
|
||||
DisplayMetrics dm = new DisplayMetrics();
|
||||
wm.getDefaultDisplay().getRealMetrics(dm);
|
||||
float density = dm.density; // 屏幕密度(0.75 / 1.0 / 1.5)
|
||||
stringIntegerHashMap.put(RecyclerViewSpacesItemDecoration.TOP_DECORATION, (int) (density * 1));//top间距
|
||||
stringIntegerHashMap.put(RecyclerViewSpacesItemDecoration.BOTTOM_DECORATION, (int) (density * 1));//底部间距
|
||||
stringIntegerHashMap.put(RecyclerViewSpacesItemDecoration.LEFT_DECORATION, (int) (density * 20));//左间距
|
||||
stringIntegerHashMap.put(RecyclerViewSpacesItemDecoration.RIGHT_DECORATION, (int) (density * 20));//右间距
|
||||
recyclerView.addItemDecoration(new RecyclerViewSpacesItemDecoration(stringIntegerHashMap));
|
||||
|
||||
mManager = new RecycleGridLayoutManager(mContext, SPAN_COUNT);
|
||||
recyclerView.setLayoutManager(mManager);
|
||||
|
||||
EquallyDividedItemDecoration equallyDividedItemDecoration = new EquallyDividedItemDecoration(SPAN_COUNT, ScreenUtils.dip2px(mContext, 1));
|
||||
recyclerView.addItemDecoration(equallyDividedItemDecoration);
|
||||
recyclerView.setNestedScrollingEnabled(false);
|
||||
recyclerView.addItemDecoration(new SpacesItemDecoration(getResources().getDimensionPixelSize(R.dimen.PX1x), getResources().getDimensionPixelSize(R.dimen.PX1x),
|
||||
getResources().getDimensionPixelSize(R.dimen.PX1x), getResources().getDimensionPixelSize(R.dimen.PX1x)));
|
||||
|
||||
((DefaultItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
|
||||
adapter = new VideoAdapter(mContext);
|
||||
adapter.setOnLongClickListener(new VideoAdapter.onItemLongClickListener() {
|
||||
mVideoAdapter = new VideoAdapter(mContext);
|
||||
mVideoAdapter.setOnLongClickListener(new VideoAdapter.onItemLongClickListener() {
|
||||
@Override
|
||||
public void onItemLongClick(String path, int position) {
|
||||
showDialog(path, position);
|
||||
}
|
||||
});
|
||||
recyclerView.setAdapter(adapter);
|
||||
recyclerView.setAdapter(mVideoAdapter);
|
||||
|
||||
mPresenter.getHomeVideo();
|
||||
refreshLayout.setRefreshing(true);
|
||||
@@ -194,7 +169,7 @@ public class VideoFragment extends BaseFragment implements VideoContact.VideoVie
|
||||
dialog.dismiss();
|
||||
File file = new File(path);
|
||||
if (file.delete()) {
|
||||
adapter.removeItem(position);
|
||||
mVideoAdapter.removeItem(position);
|
||||
ToastUtil.show("删除成功");
|
||||
} else {
|
||||
ToastUtil.show("删除失败,检查权限是否开启");
|
||||
@@ -219,7 +194,7 @@ public class VideoFragment extends BaseFragment implements VideoContact.VideoVie
|
||||
} else {
|
||||
cl_nodata.setVisibility(View.GONE);
|
||||
recyclerView.setVisibility(View.VISIBLE);
|
||||
adapter.setData(video);
|
||||
mVideoAdapter.setData(video);
|
||||
}
|
||||
refreshLayout.setRefreshing(false);
|
||||
}
|
||||
@@ -230,10 +205,6 @@ public class VideoFragment extends BaseFragment implements VideoContact.VideoVie
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//在这里处理任务执行中的状态,如进度进度条的刷新
|
||||
@Download.onTaskRunning
|
||||
void running(DownloadTask task) {
|
||||
|
||||
@@ -33,7 +33,9 @@ public class Utils {
|
||||
if (fileS == 0) {
|
||||
return wrongSize;
|
||||
}
|
||||
if (fileS < 1048576) {
|
||||
if (fileS < 1024) {
|
||||
fileSizeString = df.format((double) fileS) + "MB";
|
||||
} else if (fileS < 1048576) {
|
||||
fileSizeString = df.format((double) fileS / 1024) + "GB";
|
||||
} else {
|
||||
fileSizeString = df.format((double) fileS / 1048576) + "TB";
|
||||
|
||||
BIN
app/src/main/res/drawable-hdpi/icon_vip.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 1.9 KiB |
17
app/src/main/res/drawable/bt_vip_backround.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- 内部颜色 -->
|
||||
<solid android:color="@color/btn_sure" />
|
||||
<!-- 圆角的幅度 -->
|
||||
<corners
|
||||
android:bottomLeftRadius="@dimen/dp_16"
|
||||
android:bottomRightRadius="@dimen/dp_16"
|
||||
android:topLeftRadius="@dimen/dp_16"
|
||||
android:topRightRadius="@dimen/dp_16" />
|
||||
|
||||
<padding
|
||||
android:bottom="@dimen/dp_4"
|
||||
android:left="@dimen/dp_12"
|
||||
android:right="@dimen/dp_12"
|
||||
android:top="@dimen/dp_4" />
|
||||
</shape>
|
||||
17
app/src/main/res/drawable/vip_background.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@android:color/white" />
|
||||
|
||||
<corners
|
||||
android:bottomLeftRadius="@dimen/dp_8"
|
||||
android:bottomRightRadius="@dimen/dp_8"
|
||||
android:topLeftRadius="@dimen/dp_8"
|
||||
android:topRightRadius="@dimen/dp_8" />
|
||||
|
||||
<padding
|
||||
android:bottom="@dimen/dp_8"
|
||||
android:left="@dimen/dp_8"
|
||||
android:right="@dimen/dp_8"
|
||||
android:top="@dimen/dp_8" />
|
||||
|
||||
</shape>
|
||||
@@ -1,267 +1,137 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".activity.main.MainActivity">
|
||||
|
||||
<data>
|
||||
|
||||
<variable
|
||||
name="click"
|
||||
type="com.uiui.videoplayer.activity.main.MainActivity.Click" />
|
||||
</data>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/constraintLayout3"
|
||||
android:layout_width="@dimen/dp_120"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/white"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/constraintLayout2"
|
||||
android:id="@+id/constraintLayout3"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dp_32"
|
||||
android:layout_marginTop="@dimen/dp_16"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_back"
|
||||
android:layout_width="@dimen/dp_16"
|
||||
android:layout_height="@dimen/dp_16"
|
||||
android:layout_marginStart="@dimen/dp_4"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/back"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="家庭空间"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_12"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/constraintLayout2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dp_32"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/constraintLayout2">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/cl_pic"
|
||||
android:layout_width="@dimen/dp_100"
|
||||
android:layout_height="@dimen/dp_64"
|
||||
android:layout_gravity="end"
|
||||
android:layout_marginTop="@dimen/dp_16"
|
||||
android:background="@drawable/alarm_pressed_background">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_pic"
|
||||
android:layout_width="@dimen/dp_44"
|
||||
android:layout_height="@dimen/dp_44"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/home_icon_picture_normal"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_8"
|
||||
android:onClick="@{click::exit}"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/textView2"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_back"
|
||||
android:layout_width="@dimen/dp_16"
|
||||
android:layout_height="@dimen/dp_16"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/back"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="家庭空间"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_12"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/iv_back"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dp_8"
|
||||
android:text="图片"
|
||||
android:textSize="@dimen/sp_10"
|
||||
android:background="@drawable/bt_vip_backround"
|
||||
android:onClick="@{click::toVip}"
|
||||
android:text="会员权益"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/sp_8"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/cl_video"
|
||||
android:layout_width="@dimen/dp_100"
|
||||
android:layout_height="@dimen/dp_64"
|
||||
android:layout_gravity="end"
|
||||
android:layout_marginTop="@dimen/dp_16"
|
||||
app:layout_constraintStart_toEndOf="@+id/cl_pic"
|
||||
app:layout_constraintTop_toTopOf="@+id/cl_pic">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/constraintLayout2">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_video"
|
||||
android:layout_width="@dimen/dp_44"
|
||||
android:layout_height="@dimen/dp_44"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/home_icon_video_normal"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/textView"
|
||||
<com.flyco.tablayout.SlidingTabLayout
|
||||
android:id="@+id/main_sliding_tab_layout"
|
||||
android:layout_width="@dimen/dp_100"
|
||||
android:layout_height="@dimen/dp_24"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:tl_indicator_color="@color/black"
|
||||
app:tl_indicator_style="NORMAL"
|
||||
app:tl_indicator_width_equal_title="true"
|
||||
app:tl_tab_space_equal="true"
|
||||
app:tl_textBold="SELECT"
|
||||
app:tl_textSelectColor="@color/black"
|
||||
app:tl_textSelectSize="@dimen/sp_11"
|
||||
app:tl_textSize="@dimen/sp_10"
|
||||
app:tl_textUnSelectColor="@color/gray"
|
||||
app:tl_textUnSelectSize="@dimen/sp_10" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
android:id="@+id/tv_version"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dp_8"
|
||||
android:maxLines="1"
|
||||
android:text="视频"
|
||||
android:textSize="@dimen/sp_10"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_7"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/main_sliding_tab_layout"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/cl_doc"
|
||||
android:layout_width="@dimen/dp_100"
|
||||
android:layout_height="@dimen/dp_64"
|
||||
android:layout_gravity="end"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintStart_toEndOf="@+id/cl_pic"
|
||||
app:layout_constraintTop_toTopOf="@+id/cl_pic">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_doc"
|
||||
android:layout_width="@dimen/dp_44"
|
||||
android:layout_height="@dimen/dp_44"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/home_icon_doc_normal"
|
||||
<androidx.viewpager.widget.ViewPager
|
||||
android:id="@+id/viewPager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/textView3"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
app:layout_constraintTop_toBottomOf="@id/main_sliding_tab_layout" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView3"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dp_8"
|
||||
android:maxLines="1"
|
||||
android:text="文档"
|
||||
android:textSize="@dimen/sp_10"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_version"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/dp_8"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_7"
|
||||
app:layout_constraintBottom_toTopOf="@+id/constraintLayout5"
|
||||
app:layout_constraintEnd_toEndOf="@+id/constraintLayout5"
|
||||
app:layout_constraintStart_toStartOf="@+id/constraintLayout5" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/constraintLayout5"
|
||||
android:layout_width="@dimen/dp_90"
|
||||
android:layout_height="@dimen/dp_48"
|
||||
android:layout_marginBottom="@dimen/dp_24"
|
||||
android:background="@drawable/space_background"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_space"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/sp_13"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="0.5GB/1GB" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_rank"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/sp_10"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_space"
|
||||
tools:text="普通版本" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/home_background_color"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/constraintLayout3"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/constraintLayout4"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/dp_32"
|
||||
android:layout_marginTop="@dimen/dp_16"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dp_4"
|
||||
android:text="按时间顺序排序"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_10"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/imageView"
|
||||
app:layout_constraintEnd_toStartOf="@+id/imageView"
|
||||
app:layout_constraintTop_toTopOf="@+id/imageView" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="@dimen/dp_10"
|
||||
android:layout_height="@dimen/dp_10"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/icon_dropdown"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/constraintLayout4" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</layout>
|
||||
267
app/src/main/res/layout/activity_main_land.xml
Normal file
@@ -0,0 +1,267 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".activity.main.MainActivity">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/constraintLayout3"
|
||||
android:layout_width="@dimen/dp_120"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/white"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/constraintLayout2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dp_32"
|
||||
android:layout_marginTop="@dimen/dp_16"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_back"
|
||||
android:layout_width="@dimen/dp_16"
|
||||
android:layout_height="@dimen/dp_16"
|
||||
android:layout_marginStart="@dimen/dp_4"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/back"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="家庭空间"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_12"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/constraintLayout2">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/cl_pic"
|
||||
android:layout_width="@dimen/dp_100"
|
||||
android:layout_height="@dimen/dp_64"
|
||||
android:layout_gravity="end"
|
||||
android:layout_marginTop="@dimen/dp_16"
|
||||
android:background="@drawable/alarm_pressed_background">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_pic"
|
||||
android:layout_width="@dimen/dp_44"
|
||||
android:layout_height="@dimen/dp_44"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/home_icon_picture_normal"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/textView2"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dp_8"
|
||||
android:text="图片"
|
||||
android:textSize="@dimen/sp_10"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/cl_video"
|
||||
android:layout_width="@dimen/dp_100"
|
||||
android:layout_height="@dimen/dp_64"
|
||||
android:layout_gravity="end"
|
||||
android:layout_marginTop="@dimen/dp_16"
|
||||
app:layout_constraintStart_toEndOf="@+id/cl_pic"
|
||||
app:layout_constraintTop_toTopOf="@+id/cl_pic">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_video"
|
||||
android:layout_width="@dimen/dp_44"
|
||||
android:layout_height="@dimen/dp_44"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/home_icon_video_normal"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/textView"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dp_8"
|
||||
android:maxLines="1"
|
||||
android:text="视频"
|
||||
android:textSize="@dimen/sp_10"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/cl_doc"
|
||||
android:layout_width="@dimen/dp_100"
|
||||
android:layout_height="@dimen/dp_64"
|
||||
android:layout_gravity="end"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintStart_toEndOf="@+id/cl_pic"
|
||||
app:layout_constraintTop_toTopOf="@+id/cl_pic">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_doc"
|
||||
android:layout_width="@dimen/dp_44"
|
||||
android:layout_height="@dimen/dp_44"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/home_icon_doc_normal"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/textView3"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView3"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dp_8"
|
||||
android:maxLines="1"
|
||||
android:text="文档"
|
||||
android:textSize="@dimen/sp_10"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_version"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/dp_8"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_7"
|
||||
app:layout_constraintBottom_toTopOf="@+id/constraintLayout5"
|
||||
app:layout_constraintEnd_toEndOf="@+id/constraintLayout5"
|
||||
app:layout_constraintStart_toStartOf="@+id/constraintLayout5" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/constraintLayout5"
|
||||
android:layout_width="@dimen/dp_90"
|
||||
android:layout_height="@dimen/dp_48"
|
||||
android:layout_marginBottom="@dimen/dp_24"
|
||||
android:background="@drawable/space_background"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_space"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/sp_13"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="0.5GB/1GB" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_rank"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/sp_10"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_space"
|
||||
tools:text="普通版本" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/home_background_color"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/constraintLayout3"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/constraintLayout4"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/dp_32"
|
||||
android:layout_marginTop="@dimen/dp_16"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dp_4"
|
||||
android:text="按时间顺序排序"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_10"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/imageView"
|
||||
app:layout_constraintEnd_toStartOf="@+id/imageView"
|
||||
app:layout_constraintTop_toTopOf="@+id/imageView" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="@dimen/dp_10"
|
||||
android:layout_height="@dimen/dp_10"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/icon_dropdown"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/constraintLayout4" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
80
app/src/main/res/layout/activity_vip.xml
Normal file
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<data>
|
||||
|
||||
<variable
|
||||
name="click"
|
||||
type="com.uiui.videoplayer.activity.vip.VipActivity.Click" />
|
||||
|
||||
</data>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:onClick="@{click::exit}">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="@dimen/dp_240"
|
||||
android:layout_height="@dimen/dp_160"
|
||||
android:background="@drawable/vip_background"
|
||||
android:onClick="@{click::empty}"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:soundEffectsEnabled="false"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="会员权益说明"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_11"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/dp_44"
|
||||
android:layout_height="@dimen/dp_44"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="@dimen/dp_16"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/icon_vip" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_space_free"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="@dimen/dp_16"
|
||||
android:text="@string/space_free"
|
||||
android:textColor="@color/gray"
|
||||
android:textSize="@dimen/sp_9" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_space_used"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="@dimen/dp_16"
|
||||
android:text="@string/space_used"
|
||||
android:textColor="@color/gray"
|
||||
android:textSize="@dimen/sp_9" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</layout>
|
||||
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
tools:context=".fragment.pic.PictureFragment">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
@@ -15,8 +15,7 @@
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/swipeRefreshLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
>
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
@@ -24,6 +23,7 @@
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerView"
|
||||
android:overScrollMode="never"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
tools:context=".fragment.pic.PictureFragment">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
@@ -17,13 +17,13 @@
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/swipeRefreshLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
>
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
android:layout_height="match_parent"
|
||||
android:overScrollMode="never" />
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
|
||||
@@ -9,10 +9,9 @@
|
||||
<com.shehuan.niv.NiceImageView
|
||||
android:id="@+id/iv_pic"
|
||||
android:layout_width="@dimen/dp_120"
|
||||
android:layout_height="@dimen/dp_120"
|
||||
android:layout_height="@dimen/dp_160"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop"
|
||||
app:corner_radius="@dimen/dp_4"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
@@ -22,7 +21,6 @@
|
||||
android:id="@+id/tv_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/dp_2"
|
||||
android:maxLines="2"
|
||||
android:textColor="@color/lightGray"
|
||||
android:textSize="@dimen/sp_9"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/constraintLayout"
|
||||
android:layout_width="@dimen/dp_120"
|
||||
android:layout_height="@dimen/dp_120"
|
||||
android:layout_height="@dimen/dp_160"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
@@ -18,10 +18,8 @@
|
||||
android:id="@+id/video_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="@dimen/dp_2"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop"
|
||||
app:corner_radius="@dimen/dp_4"
|
||||
app:is_cover_src="true" />
|
||||
|
||||
<com.shehuan.niv.NiceImageView
|
||||
|
||||
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 50 KiB |
@@ -4,4 +4,6 @@
|
||||
|
||||
<!-- TODO: Remove or change this placeholder text -->
|
||||
<string name="hello_blank_fragment">Hello blank fragment</string>
|
||||
<string name="space_free">免费存储空间:%s/%s</string>
|
||||
<string name="space_used">剩余使用空间:%s</string>
|
||||
</resources>
|
||||
|
||||
@@ -7,15 +7,16 @@
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
<item name="android:windowBackground">@color/colorBackground</item>
|
||||
<item name="android:navigationBarColor">?attr/colorPrimary</item>
|
||||
|
||||
</style>
|
||||
|
||||
<!-- <!– Base application theme. –>-->
|
||||
<!-- <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">-->
|
||||
<!-- <!– Customize your theme here. –>-->
|
||||
<!-- <item name="colorPrimary">@color/white</item>-->
|
||||
<!-- <item name="colorPrimaryDark">@color/white</item>-->
|
||||
<!-- <item name="colorAccent">@color/defaultColor</item>-->
|
||||
<!-- </style>-->
|
||||
<!-- <!– Base application theme. –>-->
|
||||
<!-- <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">-->
|
||||
<!-- <!– Customize your theme here. –>-->
|
||||
<!-- <item name="colorPrimary">@color/white</item>-->
|
||||
<!-- <item name="colorPrimaryDark">@color/white</item>-->
|
||||
<!-- <item name="colorAccent">@color/defaultColor</item>-->
|
||||
<!-- </style>-->
|
||||
|
||||
<style name="CustomDialog" parent="android:style/Theme.Dialog">
|
||||
<!--背景颜色及和透明程度-->
|
||||
@@ -30,4 +31,24 @@
|
||||
<item name="android:backgroundDimEnabled">true</item>
|
||||
</style>
|
||||
|
||||
<style name="activity_styles" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- <item name="android:windowFullscreen">true</item>-->
|
||||
<!--设置dialog的背景-->
|
||||
<item name="android:windowBackground">@android:color/transparent</item>
|
||||
<!--设置Dialog的windowFrame框为无-->
|
||||
<item name="android:windowFrame">@null</item>
|
||||
<!--设置无标题-->
|
||||
<item name="windowNoTitle">true</item>
|
||||
<!--是否浮现在activity之上-->
|
||||
<item name="android:windowIsFloating">false</item>
|
||||
<!--是否半透明-->
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
<!--设置窗口内容不覆盖-->
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
<!--设置动画,在这里使用让它继承系统的Animation.Dialog-->
|
||||
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
|
||||
<!--背景是否模糊显示-->
|
||||
<item name="android:backgroundDimEnabled">true</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -25,6 +25,8 @@ public class RemoteManager {
|
||||
public static final String hidePackageKey = "HIDE_PACKAGE_NAME";
|
||||
public static final String disablePackageKey = "DISABLE_PACKAGE_NAME";
|
||||
|
||||
private static boolean mServiceConnected = false;
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private static RemoteManager sInstance;
|
||||
private Context mContext;
|
||||
@@ -41,6 +43,7 @@ public class RemoteManager {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
Log.e(TAG, "onServiceConnected: " + name);
|
||||
mServiceConnected = true;
|
||||
mIGetInfoInterface = IGetInfoInterface.Stub.asInterface(service);
|
||||
try {
|
||||
for (ConnectedListener listener : mListeners) {
|
||||
@@ -102,6 +105,9 @@ public class RemoteManager {
|
||||
|
||||
public void setListener(ConnectedListener listener) {
|
||||
mListeners.add(listener);
|
||||
if (mServiceConnected) {
|
||||
listener.onConnected();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeListener(ConnectedListener listener) {
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
rootProject.name='UIUI家庭空间'
|
||||
include ':app', ':JZVideo', ':niceimageview'
|
||||
include ':app', ':JZVideo', ':niceimageview', ':FlycoTabLayoutZ_Lib'
|
||||
|
||||