Merge branch 'feature/v1.0.0' of http://gitlab.zhidaoauto.com/ecos/yycp-service/Launcher into feature/v1.0.0

This commit is contained in:
unknown
2020-02-12 11:47:28 +08:00
42 changed files with 1106 additions and 632 deletions

View File

@@ -12,6 +12,7 @@ ext {
dependencies = [
// androidx
androidxappcompat : "androidx.appcompat:appcompat:1.0.2",
androidxccorektx : "androidx.core:core-ktx:1.0.2",
androidxconstraintlayout : "androidx.constraintlayout:constraintlayout:1.1.3",
androidxmultidex : "androidx.multidex:multidex:2.0.1",
androidxviewpager2 : "androidx.viewpager2:viewpager2:1.0.0",
@@ -109,7 +110,7 @@ ext {
moduleadcard : "com.mogo.module:module-adcard:${MOGO_MODULE_AD_CARD_VERSION}",
modulefreshnews : "com.mogo.module:module-freshnews:${MOGO_MODULE_FRESH_NEWS_VERSION}",
//统一返回键
mogomoduleback : "com.mogo.module:module-back:${MOGO_MODULE_BACK_VERSION}",
mogomoduleback : "com.mogo.module:module-back:${MOGO_MODULE_BACK_VERSION}",
// 长链
socketsdk : 'com.zhidao.socketsdk:socketsdk:2.1.0',
socketsdkconnsvrprotoco : 'com.zhidao.ptech:connsvr-protoco:0.1.23',
@@ -122,5 +123,13 @@ ext {
accountsdk : "com.zhidao.accountservice:account-sdk:1.0.5",
// crash
crashSdk : "com.zhidaoauto.crash.log:library:1.0.5",
kotlinstdlibjdk7 : "org.jetbrains.kotlin:kotlin-stdlib-jdk7",
//探路
videoarmv7 : "com.shuyu:gsyVideoPlayer-armv7a:7.1.2",
videoarm64 : "com.shuyu:gsyVideoPlayer-arm64:7.1.2",
videojava : "com.shuyu:gsyVideoPlayer-java:7.1.2",
eventbus : "org.greenrobot:eventbus:3.1.1",
]
}

View File

@@ -62,7 +62,7 @@ public class AbsMogoApplication extends Application {
Analytics.getInstance().setAppKey( "6bbe7e0e1ecd8e2f8dc336e1678a2791" );
// 0 - debug 近实时上报积累一条埋点上报或者积累3秒上报一次。
// 2 - 本地缓存聚合上报积累30条埋点上报或者积累60秒上报一次。
AnalyticsConfig.getInstance( sApp ).setMode( DebugConfig.isDebug() ? 0 : 2 );
AnalyticsConfig.getInstance( sApp ).setMode( DebugConfig.isDebug() ? 2 : 2 );
AnalyticsConfig.getInstance( sApp ).shouldLog( DebugConfig.isDebug() );
// 初始化 arouter

View File

@@ -14,7 +14,7 @@ import com.alibaba.android.arouter.launcher.ARouter;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.mogo.commons.mvp.MvpFragment;
import com.mogo.module.apps.model.AppInfo;
import com.mogo.module.apps.view.LinePageIndicator;
import com.mogo.module.apps.view.PagerSlidingTabStripV2;
import com.mogo.service.MogoServicePaths;
import com.mogo.service.fragmentmanager.IMogoFragmentManager;
import com.mogo.utils.logger.Logger;
@@ -40,7 +40,7 @@ public class AppsFragment extends MvpFragment< AppsView, AppsPresenter > impleme
private IMogoFragmentManager mMogoFragmentManager;
private View mLoadingView;
private LinePageIndicator mIndicator;
private PagerSlidingTabStripV2 mIndicator;
@Override
protected int getLayoutId() {
@@ -77,6 +77,7 @@ public class AppsFragment extends MvpFragment< AppsView, AppsPresenter > impleme
mLoadingView = findViewById( R.id.module_apps_id_loading );
mLoadingView.setVisibility( View.VISIBLE );
mIndicator = findViewById( R.id.module_apps_id_indicator );
mIndicator.setOpenPadding( true );
}
@NonNull
@@ -93,6 +94,7 @@ public class AppsFragment extends MvpFragment< AppsView, AppsPresenter > impleme
@Override
public void renderApps( Map< Integer, List< AppInfo > > appInfos ) {
mAppsPager.setOffscreenPageLimit( appInfos.size() );
mLoadingView.setVisibility( View.GONE );
if ( mAppsPagerAdapter == null ) {
mAppsPagerAdapter = new AppsPagerAdapter( appInfos );

View File

@@ -1,5 +1,6 @@
package com.mogo.module.apps;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -8,8 +9,12 @@ import android.widget.GridView;
import androidx.annotation.NonNull;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.mogo.module.apps.model.AppInfo;
import com.mogo.module.apps.view.PagerIndicator;
import com.mogo.module.apps.view.PagerSlidingTabStripV2;
import com.mogo.utils.ResourcesHelper;
import java.util.List;
import java.util.Map;
@@ -20,7 +25,7 @@ import java.util.Map;
* <p>
* 描述
*/
public class AppsPagerAdapter extends PagerAdapter {
public class AppsPagerAdapter extends PagerAdapter implements PagerSlidingTabStripV2.ViewTabProvider {
private Map< Integer, List< AppInfo > > mPagedApps;
private OnAppClickedListener mOnAppClickedListener;
@@ -82,4 +87,9 @@ public class AppsPagerAdapter extends PagerAdapter {
public interface OnAppClickedListener {
void onClick( AppInfo appInfo, int position );
}
@Override
public View getPageTabView( Context context, int position ) {
return new PagerIndicator( context );
}
}

View File

@@ -1,455 +0,0 @@
/*
* Copyright (C) 2012 Jake Wharton
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mogo.module.apps.view;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import androidx.core.view.MotionEventCompat;
import androidx.core.view.ViewConfigurationCompat;
import androidx.viewpager.widget.ViewPager;
import com.mogo.module.apps.R;
/**
* Draws a line for each page. The current page line is colored differently
* than the unselected page lines.
*/
public class LinePageIndicator extends View implements PageIndicator {
private static final int INVALID_POINTER = -1;
private final Paint mPaintUnselected = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint mPaintSelected = new Paint(Paint.ANTI_ALIAS_FLAG);
private ViewPager mViewPager;
private ViewPager.OnPageChangeListener mListener;
private int mCurrentPage;
private boolean mCentered;
private float mLineWidth;
private float mGapWidth;
private int mTouchSlop;
private float mLastMotionX = -1;
private int mActivePointerId = INVALID_POINTER;
private boolean mIsDragging;
public LinePageIndicator(Context context) {
this(context, null);
}
public LinePageIndicator(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.vpiLinePageIndicatorStyle);
}
public LinePageIndicator(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if (isInEditMode()) {
return;
}
final Resources res = getResources();
//Load defaults from resources
final int defaultSelectedColor = res.getColor(R.color.default_line_indicator_selected_color);
final int defaultUnselectedColor = res.getColor(R.color.default_line_indicator_unselected_color);
final float defaultLineWidth = res.getDimension(R.dimen.default_line_indicator_line_width);
final float defaultGapWidth = res.getDimension(R.dimen.default_line_indicator_gap_width);
final float defaultStrokeWidth = res.getDimension(R.dimen.default_line_indicator_stroke_width);
final boolean defaultCentered = res.getBoolean(R.bool.default_line_indicator_centered);
//Retrieve styles attributes
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LinePageIndicator, defStyle, 0);
mCentered = a.getBoolean(R.styleable.LinePageIndicator_centered, defaultCentered);
mLineWidth = a.getDimension(R.styleable.LinePageIndicator_lineWidth, defaultLineWidth);
mGapWidth = a.getDimension(R.styleable.LinePageIndicator_gapWidth, defaultGapWidth);
setStrokeWidth(a.getDimension(R.styleable.LinePageIndicator_strokeWidth, defaultStrokeWidth));
mPaintUnselected.setColor(a.getColor(R.styleable.LinePageIndicator_unselectedColor, defaultUnselectedColor));
mPaintSelected.setColor(a.getColor(R.styleable.LinePageIndicator_selectedColor, defaultSelectedColor));
Drawable background = a.getDrawable(R.styleable.LinePageIndicator_android_background);
if (background != null) {
setBackgroundDrawable(background);
}
a.recycle();
final ViewConfiguration configuration = ViewConfiguration.get(context);
mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
}
public void setCentered(boolean centered) {
mCentered = centered;
invalidate();
}
public boolean isCentered() {
return mCentered;
}
public void setUnselectedColor(int unselectedColor) {
mPaintUnselected.setColor(unselectedColor);
invalidate();
}
public int getUnselectedColor() {
return mPaintUnselected.getColor();
}
public void setSelectedColor(int selectedColor) {
mPaintSelected.setColor(selectedColor);
invalidate();
}
public int getSelectedColor() {
return mPaintSelected.getColor();
}
public void setLineWidth(float lineWidth) {
mLineWidth = lineWidth;
invalidate();
}
public float getLineWidth() {
return mLineWidth;
}
public void setStrokeWidth(float lineHeight) {
mPaintSelected.setStrokeWidth(lineHeight);
mPaintUnselected.setStrokeWidth(lineHeight);
invalidate();
}
public float getStrokeWidth() {
return mPaintSelected.getStrokeWidth();
}
public void setGapWidth(float gapWidth) {
mGapWidth = gapWidth;
invalidate();
}
public float getGapWidth() {
return mGapWidth;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mViewPager == null) {
return;
}
final int count = mViewPager.getAdapter().getCount();
if (count == 0) {
return;
}
if (mCurrentPage >= count) {
setCurrentItem(count - 1);
return;
}
final float lineWidthAndGap = mLineWidth + mGapWidth;
final float indicatorWidth = (count * lineWidthAndGap) - mGapWidth;
final float paddingTop = getPaddingTop();
final float paddingLeft = getPaddingLeft();
final float paddingRight = getPaddingRight();
float verticalOffset = paddingTop + ((getHeight() - paddingTop - getPaddingBottom()) / 2.0f);
float horizontalOffset = paddingLeft;
if (mCentered) {
horizontalOffset += ((getWidth() - paddingLeft - paddingRight) / 2.0f) - (indicatorWidth / 2.0f);
}
//Draw stroked circles
for (int i = 0; i < count; i++) {
float dx1 = horizontalOffset + (i * lineWidthAndGap);
float dx2 = dx1 + mLineWidth;
canvas.drawLine(dx1, verticalOffset, dx2, verticalOffset, (i == mCurrentPage) ? mPaintSelected : mPaintUnselected);
}
}
public boolean onTouchEvent(MotionEvent ev) {
if (super.onTouchEvent(ev)) {
return true;
}
if ((mViewPager == null) || (mViewPager.getAdapter().getCount() == 0)) {
return false;
}
final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
mLastMotionX = ev.getX();
break;
case MotionEvent.ACTION_MOVE: {
final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
final float x = MotionEventCompat.getX(ev, activePointerIndex);
final float deltaX = x - mLastMotionX;
if (!mIsDragging) {
if (Math.abs(deltaX) > mTouchSlop) {
mIsDragging = true;
}
}
if (mIsDragging) {
mLastMotionX = x;
if (mViewPager.isFakeDragging() || mViewPager.beginFakeDrag()) {
mViewPager.fakeDragBy(deltaX);
}
}
break;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (!mIsDragging) {
final int count = mViewPager.getAdapter().getCount();
final int width = getWidth();
final float halfWidth = width / 2f;
final float sixthWidth = width / 6f;
if ((mCurrentPage > 0) && (ev.getX() < halfWidth - sixthWidth)) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage - 1);
}
return true;
} else if ((mCurrentPage < count - 1) && (ev.getX() > halfWidth + sixthWidth)) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage + 1);
}
return true;
}
}
mIsDragging = false;
mActivePointerId = INVALID_POINTER;
if (mViewPager.isFakeDragging()) {
mViewPager.endFakeDrag();
}
break;
case MotionEventCompat.ACTION_POINTER_DOWN: {
final int index = MotionEventCompat.getActionIndex(ev);
mLastMotionX = MotionEventCompat.getX(ev, index);
mActivePointerId = MotionEventCompat.getPointerId(ev, index);
break;
}
case MotionEventCompat.ACTION_POINTER_UP:
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
if (pointerId == mActivePointerId) {
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
}
mLastMotionX = MotionEventCompat.getX(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId));
break;
default:
break;
}
return true;
}
@Override
public void setViewPager(ViewPager viewPager) {
if (mViewPager == viewPager) {
return;
}
if (mViewPager != null) {
//Clear us from the old pager.
// mViewPager.setOnPageChangeListener(null);
}
if (viewPager.getAdapter() == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
mViewPager = viewPager;
mViewPager.setOnPageChangeListener(this);
invalidate();
}
@Override
public void setViewPager(ViewPager view, int initialPosition) {
setViewPager(view);
setCurrentItem(initialPosition);
}
@Override
public void setCurrentItem(int item) {
if (mViewPager == null) {
throw new IllegalStateException("ViewPager has not been bound.");
}
mViewPager.setCurrentItem(item);
mCurrentPage = item;
invalidate();
}
@Override
public void notifyDataSetChanged() {
invalidate();
}
@Override
public void onPageScrollStateChanged(int state) {
if (mListener != null) {
mListener.onPageScrollStateChanged(state);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (mListener != null) {
mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
@Override
public void onPageSelected(int position) {
mCurrentPage = position;
invalidate();
if (mListener != null) {
mListener.onPageSelected(position);
}
}
@Override
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
mListener = listener;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
}
/**
* Determines the width of this view
*
* @param measureSpec
* A measureSpec packed into an int
* @return The width of the view, honoring constraints from measureSpec
*/
private int measureWidth(int measureSpec) {
float result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if ((specMode == MeasureSpec.EXACTLY) || (mViewPager == null)) {
//We were told how big to be
result = specSize;
} else {
//Calculate the width according the views count
final int count = mViewPager.getAdapter().getCount();
result = getPaddingLeft() + getPaddingRight() + (count * mLineWidth) + ((count - 1) * mGapWidth);
//Respect AT_MOST value if that was what is called for by measureSpec
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return (int)Math.ceil(result);
}
/**
* Determines the height of this view
*
* @param measureSpec
* A measureSpec packed into an int
* @return The height of the view, honoring constraints from measureSpec
*/
private int measureHeight(int measureSpec) {
float result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
//We were told how big to be
result = specSize;
} else {
//Measure the height
result = mPaintSelected.getStrokeWidth() + getPaddingTop() + getPaddingBottom();
//Respect AT_MOST value if that was what is called for by measureSpec
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return (int)Math.ceil(result);
}
@Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState)state;
super.onRestoreInstanceState(savedState.getSuperState());
mCurrentPage = savedState.currentPage;
requestLayout();
}
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.currentPage = mCurrentPage;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPage;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentPage = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPage);
}
@SuppressWarnings("UnusedDeclaration")
public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}

View File

@@ -1,64 +0,0 @@
/*
* Copyright (C) 2011 Patrik Akerfeldt
* Copyright (C) 2011 Jake Wharton
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mogo.module.apps.view;
import androidx.viewpager.widget.ViewPager;
/**
* A PageIndicator is responsible to show an visual indicator on the total views
* number and the current visible view.
*/
public interface PageIndicator extends ViewPager.OnPageChangeListener {
/**
* Bind the indicator to a ViewPager.
*
* @param view
*/
void setViewPager( ViewPager view );
/**
* Bind the indicator to a ViewPager.
*
* @param view
* @param initialPosition
*/
void setViewPager( ViewPager view, int initialPosition );
/**
* <p>Set the current page of both the ViewPager and indicator.</p>
*
* <p>This <strong>must</strong> be used if you need to set the page before
* the views are drawn on screen (e.g., default start page).</p>
*
* @param item
*/
void setCurrentItem( int item );
/**
* Set a page change listener which will receive forwarded events.
*
* @param listener
*/
void setOnPageChangeListener( ViewPager.OnPageChangeListener listener );
/**
* Notify the indicator that the fragment list has changed.
*/
void notifyDataSetChanged();
}

View File

@@ -0,0 +1,41 @@
package com.mogo.module.apps.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
import com.mogo.module.apps.R;
/**
* @author congtaowang
* @since 2020-02-11
* <p>
* 描述
*/
public class PagerIndicator extends LinearLayout implements PagerSlidingTabStripV2.SelectedState {
private View mIndicator;
public PagerIndicator( Context context ) {
this( context, null );
}
public PagerIndicator( Context context, @Nullable AttributeSet attrs ) {
this( context, attrs, 0 );
}
public PagerIndicator( Context context, @Nullable AttributeSet attrs, int defStyleAttr ) {
super( context, attrs, defStyleAttr );
LayoutInflater.from( context ).inflate( R.layout.modle_apps_page_indicator, this, true );
mIndicator = findViewById( R.id.module_apps_id_indicator_dot );
}
@Override
public void setSelectedState( boolean isSelected ) {
mIndicator.setSelected( isSelected );
}
}

View File

@@ -0,0 +1,763 @@
/*
* Copyright (C) 2013 Andreas Stuetz <andreas.stuetz@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mogo.module.apps.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.HorizontalScrollView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.viewpager.widget.ViewPager;
import com.mogo.module.apps.R;
import com.mogo.utils.WindowUtils;
import java.util.Locale;
/**
* Reference : http://doc.okbase.net/HarryWeasley/archive/121430.html
*/
public class PagerSlidingTabStripV2 extends HorizontalScrollView {
public interface IconTabProvider {
public int getPageIconResId( int position );
}
public interface ViewTabProvider {
public View getPageTabView( Context context, int position );
}
public interface SelectedState {
void setSelectedState( boolean isSelected );
}
// @formatter:off
private static final int[] ATTRS = new int[]{
android.R.attr.textSize,
android.R.attr.textColor
};
// @formatter:on
public interface OnBeforeTabAction {
boolean doAction( int position );
}
private LinearLayout.LayoutParams defaultTabLayoutParams;
private LinearLayout.LayoutParams expandedTabLayoutParams;
private final PageListener pageListener = new PageListener();
public ViewPager.OnPageChangeListener delegatePageListener;
private LinearLayout tabsContainer;
private ViewPager pager;
private int tabCount;
private int currentPosition = 0;
private int selectedPosition = 0;
private float currentPositionOffset = 0f;
private Paint rectPaint;
private Paint dividerPaint;
private int indicatorColor = 0xFF666666;
private int underlineColor = 0x1A000000;
private int dividerColor = 0x1A000000;
private boolean shouldExpand = false;
private boolean textAllCaps = true;
private int scrollOffset = 52;
private int indicatorHeight = 8;
private int underlineHeight = 2;
private int dividerPadding = 12;
private int tabPadding = 24;
private int dividerWidth = 1;
private int indicatorMarginBottom = 0;
private int indicatorMarginLeft = 0;
private int indicatorMarginRight = 0;
private int tabTextSize = 13;
private int tabTextColor = 0xFF666666;
private int selectedTabTextColor = 0xFF666666;
private Typeface tabTypeface = null;
private int tabTypefaceStyle = Typeface.NORMAL;
private int lastScrollX = 0;
private int tabBackgroundResId = R.drawable.module_apps_pager_sliding_background_tab;
public static final int INDICATOR_MODE_UNDERLINE = -1;
public static final int INDICATOR_MODE_SHADOW = 1;
public static final int INDICATOR_MODE_RES = 2;
private int indicatorMode = INDICATOR_MODE_SHADOW;
private Drawable indicatorRes;
public static final int INDICATOR_FIT_MODE_AUTO = 0;
public static final int INDICATOR_FIT_MODE_FIXED = 1;
private int indicatorFitMode = INDICATOR_FIT_MODE_AUTO;
private float indicatorFixedSize = 0;
private Locale locale;
private OnBeforeTabAction onBeforeTabAction;
private boolean openPadding = false;
public boolean isOpenPadding() {
return openPadding;
}
public void setOpenPadding( boolean openPadding ) {
this.openPadding = openPadding;
}
public PagerSlidingTabStripV2( Context context ) {
this( context, null );
}
public PagerSlidingTabStripV2( Context context, AttributeSet attrs ) {
this( context, attrs, 0 );
}
public PagerSlidingTabStripV2( Context context, AttributeSet attrs, int defStyle ) {
super( context, attrs, defStyle );
setFillViewport( true );
setWillNotDraw( false );
tabsContainer = new LinearLayout( context );
tabsContainer.setOrientation( LinearLayout.HORIZONTAL );
tabsContainer.setLayoutParams( new LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT ) );
addView( tabsContainer );
DisplayMetrics dm = getResources().getDisplayMetrics();
scrollOffset = ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm );
indicatorHeight = ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm );
underlineHeight = ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, underlineHeight, dm );
dividerPadding = ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm );
tabPadding = ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm );
dividerWidth = ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm );
tabTextSize = ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_SP, tabTextSize, dm );
indicatorMarginBottom = ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, indicatorMarginBottom, dm );
indicatorMarginLeft = ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, indicatorMarginLeft, dm );
indicatorMarginRight = ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, indicatorMarginRight, dm );
// get system attrs (android:textSize and android:textColor)
TypedArray a = context.obtainStyledAttributes( attrs, ATTRS );
tabTextSize = a.getDimensionPixelSize( 0, tabTextSize );
tabTextColor = a.getColor( 1, tabTextColor );
a.recycle();
// get custom attrs
a = context.obtainStyledAttributes( attrs, R.styleable.PagerSlidingTabStripV2 );
indicatorColor = a.getColor( R.styleable.PagerSlidingTabStripV2_pstsV2IndicatorColor, indicatorColor );
//tab文字选中时的颜色,默认和滑动指示器的颜色一致
selectedTabTextColor = a.getColor( R.styleable.PagerSlidingTabStripV2_pstsV2SelectedTabTextColor, indicatorColor );
tabTextColor = a.getColor( R.styleable.PagerSlidingTabStripV2_pstsV2TabTextColorValue, tabTextColor );
underlineColor = a.getColor( R.styleable.PagerSlidingTabStripV2_pstsV2UnderlineColor, underlineColor );
dividerColor = a.getColor( R.styleable.PagerSlidingTabStripV2_pstsV2DividerColor, dividerColor );
indicatorHeight = a.getDimensionPixelSize( R.styleable.PagerSlidingTabStripV2_pstsV2IndicatorHeight, indicatorHeight );
underlineHeight = a.getDimensionPixelSize( R.styleable.PagerSlidingTabStripV2_pstsV2UnderlineHeight, underlineHeight );
dividerPadding = a.getDimensionPixelSize( R.styleable.PagerSlidingTabStripV2_pstsV2DividerPadding, dividerPadding );
tabPadding = a.getDimensionPixelSize( R.styleable.PagerSlidingTabStripV2_pstsV2TabPaddingLeftRight, tabPadding );
tabBackgroundResId = a.getResourceId( R.styleable.PagerSlidingTabStripV2_pstsV2TabBackground, tabBackgroundResId );
shouldExpand = a.getBoolean( R.styleable.PagerSlidingTabStripV2_pstsV2ShouldExpand, shouldExpand );
scrollOffset = a.getDimensionPixelSize( R.styleable.PagerSlidingTabStripV2_pstsV2ScrollOffset, scrollOffset );
textAllCaps = a.getBoolean( R.styleable.PagerSlidingTabStripV2_pstsV2TextAllCaps, textAllCaps );
indicatorMarginBottom = a.getDimensionPixelSize( R.styleable.PagerSlidingTabStripV2_pstsV2IndicatorMarginBottom, indicatorMarginBottom );
indicatorMarginLeft = a.getDimensionPixelSize( R.styleable.PagerSlidingTabStripV2_pstsV2IndicatorMarginLeft, indicatorMarginLeft );
indicatorMarginRight = a.getDimensionPixelSize( R.styleable.PagerSlidingTabStripV2_pstsV2IndicatorMarginRight, indicatorMarginRight );
indicatorMode = a.getInt( R.styleable.PagerSlidingTabStripV2_pstsV2IndicatorMode, INDICATOR_MODE_SHADOW );
indicatorRes = a.getDrawable( R.styleable.PagerSlidingTabStripV2_pstsV2IndicatorRes );
a.recycle();
rectPaint = new Paint();
rectPaint.setAntiAlias( true );
rectPaint.setStyle( Style.FILL );
dividerPaint = new Paint();
dividerPaint.setAntiAlias( true );
dividerPaint.setStrokeWidth( dividerWidth );
defaultTabLayoutParams = new LinearLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT );
expandedTabLayoutParams = new LinearLayout.LayoutParams( 0, LayoutParams.MATCH_PARENT, 1.0f );
if ( locale == null ) {
locale = getResources().getConfiguration().locale;
}
}
public OnBeforeTabAction getOnBeforeTabAction() {
return onBeforeTabAction;
}
public void setOnBeforeTabAction( OnBeforeTabAction onBeforeTabAction ) {
this.onBeforeTabAction = onBeforeTabAction;
}
public void setViewPager( ViewPager pager ) {
this.pager = pager;
this.currentPosition = this.selectedPosition = pager.getCurrentItem();
if ( pager.getAdapter() == null ) {
throw new IllegalStateException( "ViewPager does not have adapter instance." );
}
pager.removeOnPageChangeListener( pageListener );
pager.addOnPageChangeListener( pageListener );
notifyDataSetChanged();
}
public void setOnPageChangeListener( ViewPager.OnPageChangeListener listener ) {
this.delegatePageListener = listener;
}
public void notifyDataSetChanged() {
indicatorLineOffset = -1;
tabsContainer.removeAllViews();
tabCount = pager.getAdapter().getCount();
for ( int i = 0; i < tabCount; i++ ) {
if ( pager.getAdapter() instanceof ViewTabProvider ) {
addViewTab( i, ( ( ViewTabProvider ) pager.getAdapter() ).getPageTabView( getContext(), i ) );
} else {
addTextTab( i, TextUtils.isEmpty( pager.getAdapter().getPageTitle( i ) ) ? "" : pager.getAdapter().getPageTitle( i ).toString() );
}
}
updateTabStyles();
getViewTreeObserver().addOnGlobalLayoutListener( new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
getViewTreeObserver().removeGlobalOnLayoutListener( this );
currentPosition = pager.getCurrentItem();
scrollToChild( currentPosition, 0 );
}
} );
}
private void addTextTab( final int position, String title ) {
TextView tab = new TextView( getContext() );
tab.setText( title );
tab.setGravity( Gravity.CENTER );
tab.setSingleLine();
tab.setPadding( WindowUtils.dip2px( getContext(), 10 ),
WindowUtils.dip2px( getContext(), 3 ),
WindowUtils.dip2px( getContext(), 10 ),
WindowUtils.dip2px( getContext(), 3 ) );
LinearLayout linearLayout = new LinearLayout( getContext() );
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT );
linearLayout.addView( tab, layoutParams );
linearLayout.setGravity( Gravity.CENTER );
addTab( position, linearLayout );
}
private void addIconTab( final int position, int resId ) {
ImageButton tab = new ImageButton( getContext() );
tab.setImageResource( resId );
addTab( position, tab );
}
private void addViewTab( final int position, View v ) {
addTab( position, v );
}
public void setCurrentTab( final int position ) {
pager.post( new Runnable() {
@Override
public void run() {
pager.setCurrentItem( position, false );
}
} );
}
private void addTab( final int position, View tab ) {
tab.setFocusable( true );
tab.setOnClickListener( new OnClickListener() {
@Override
public void onClick( View v ) {
if ( getOnBeforeTabAction() != null ) {
if ( getOnBeforeTabAction().doAction( position ) ) {
pager.setCurrentItem( position, false );
}
} else {
pager.setCurrentItem( position, false );
}
}
} );
if ( openPadding ) {
tab.setPadding( position == 0 ? 0 : tabPadding, 0, tabPadding, 0 );
}
tabsContainer.addView( tab, position, shouldExpand ? expandedTabLayoutParams : defaultTabLayoutParams );
}
private void updateTabStyles() {
for ( int i = 0; i < tabCount; i++ ) {
View v = tabsContainer.getChildAt( i );
if ( v instanceof SelectedState ) {
( ( SelectedState ) v ).setSelectedState( i == selectedPosition );
} else if ( v instanceof LinearLayout ) {
TextView tab = ( TextView ) ( ( LinearLayout ) v ).getChildAt( 0 );
tab.setTextSize( TypedValue.COMPLEX_UNIT_PX, tabTextSize );
tab.setTypeface( tabTypeface, tabTypefaceStyle );
tab.setTextColor( tabTextColor );
if ( textAllCaps ) {
tab.setAllCaps( true );
}
if ( i == selectedPosition ) {
tab.setTextColor( selectedTabTextColor );
if ( indicatorMode == INDICATOR_MODE_SHADOW ) {
tab.setBackgroundResource( R.drawable.module_apps_shape_deep_blue );
}
} else {
tab.setTextColor( tabTextColor );
tab.setBackgroundResource( 0 );
}
}
}
}
private void scrollToChild( int position, int offset ) {
if ( tabCount == 0 ) {
return;
}
int newScrollX = tabsContainer.getChildAt( position ).getLeft() + offset;
if ( position > 0 || offset > 0 ) {
newScrollX -= scrollOffset;
}
if ( newScrollX != lastScrollX ) {
lastScrollX = newScrollX;
scrollTo( newScrollX, 0 );
}
}
@Override
protected void onDraw( Canvas canvas ) {
super.onDraw( canvas );
if ( isInEditMode() || tabCount == 0 ) {
return;
}
final int height = getHeight();
// draw indicator line
rectPaint.setColor( indicatorColor );
// default: line below current tab
View currentTab = tabsContainer.getChildAt( currentPosition );
float lineLeft = currentTab.getLeft();
float lineRight = currentTab.getRight();
// if there is an offset, start interpolating left and right coordinates between current and next tab
if ( currentPositionOffset > 0f && currentPosition < tabCount - 1 ) {
View nextTab = tabsContainer.getChildAt( currentPosition + 1 );
final float nextTabLeft = nextTab.getLeft();
final float nextTabRight = nextTab.getRight();
lineLeft = ( currentPositionOffset * nextTabLeft + ( 1f - currentPositionOffset ) * lineLeft );
lineRight = ( currentPositionOffset * nextTabRight + ( 1f - currentPositionOffset ) * lineRight );
}
if ( indicatorMode == INDICATOR_MODE_UNDERLINE ) {
float lineOffset = getLineOffset();
float left, right, top, bottom;
if ( indicatorFitMode == INDICATOR_FIT_MODE_AUTO ) {
left = lineLeft + lineOffset + indicatorMarginLeft;
right = lineRight - lineOffset - indicatorMarginRight;
top = height - indicatorHeight - indicatorMarginBottom;
bottom = height - indicatorMarginBottom;
} else {
left = lineLeft + lineOffset;
right = lineRight - lineOffset;
top = height - indicatorHeight - indicatorMarginBottom;
bottom = height - indicatorMarginBottom;
}
if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) {
canvas.drawRoundRect( left, top, right, bottom, 90, 90, rectPaint );
} else {
canvas.drawRect( left, top, right, bottom, rectPaint );
}
}
if ( indicatorMode == INDICATOR_MODE_RES ) {
if ( indicatorRes != null ) {
int lineOffset = ( int ) getLineOffset();
int left, right, top, bottom;
int width = indicatorRes.getIntrinsicWidth();
left = ( int ) lineLeft + lineOffset;
right = ( int ) lineRight - lineOffset;
top = height - indicatorRes.getIntrinsicHeight() - indicatorMarginBottom;
left = left + ( right - left - width ) / 2;
right = left + width;
bottom = height - indicatorMarginBottom;
indicatorRes.setBounds( left, top, right, bottom );
indicatorRes.draw( canvas );
}
}
// draw underline
rectPaint.setColor( underlineColor );
canvas.drawRect( 0, height - underlineHeight, tabsContainer.getWidth(), height, rectPaint );
// draw divider
dividerPaint.setColor( dividerColor );
for ( int i = 0; i < tabCount - 1; i++ ) {
View tab = tabsContainer.getChildAt( i );
canvas.drawLine( tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint );
}
}
private float indicatorLineOffset = -1;
private float getLineOffset() {
if ( tabsContainer.getChildCount() == 0 ) {
return 0;
}
if ( !shouldExpand ) {
return 0;
}
if ( indicatorLineOffset != -1 ) {
return indicatorLineOffset;
}
float minViewMeasuredWidth = tabsContainer.getChildAt( 0 ).getMeasuredWidth();
float minContentWidth = getTabContentWidth( tabsContainer.getChildAt( 0 ) );
for ( int i = 1; i < tabsContainer.getChildCount(); i++ ) {
float nextContentWidth = getTabContentWidth( tabsContainer.getChildAt( i ) );
if ( minContentWidth > nextContentWidth ) {
minContentWidth = nextContentWidth;
}
}
float offset = ( minViewMeasuredWidth - minContentWidth ) / 2;
return indicatorLineOffset = offset == 0 ? WindowUtils.dip2px( getContext(), 25 ) : offset;
}
private float getTabContentWidth( View tab ) {
if ( tab instanceof TextView ) {
TextPaint paint = ( ( TextView ) tab ).getPaint();
return paint.measureText( ( ( TextView ) tab ).getText().toString() );
}
return tab.getMeasuredWidth();
}
private class PageListener implements ViewPager.OnPageChangeListener {
@Override
public void onPageScrolled( int position, float positionOffset, int positionOffsetPixels ) {
currentPosition = position;
currentPositionOffset = positionOffset;
scrollToChild( position, ( int ) ( positionOffset * tabsContainer.getChildAt( position ).getWidth() ) );
invalidate();
if ( delegatePageListener != null ) {
delegatePageListener.onPageScrolled( position, positionOffset, positionOffsetPixels );
}
}
@Override
public void onPageScrollStateChanged( int state ) {
if ( state == ViewPager.SCROLL_STATE_IDLE ) {
scrollToChild( pager.getCurrentItem(), 0 );
}
if ( delegatePageListener != null ) {
delegatePageListener.onPageScrollStateChanged( state );
}
}
@Override
public void onPageSelected( int position ) {
selectedPosition = position;
updateTabStyles();
if ( delegatePageListener != null ) {
delegatePageListener.onPageSelected( position );
}
}
}
public void setIndicatorColor( int indicatorColor ) {
this.indicatorColor = indicatorColor;
invalidate();
}
public void setIndicatorColorResource( int resId ) {
this.indicatorColor = getResources().getColor( resId );
invalidate();
}
public int getIndicatorColor() {
return this.indicatorColor;
}
public void setIndicatorHeight( int indicatorLineHeightPx ) {
this.indicatorHeight = indicatorLineHeightPx;
invalidate();
}
public int getIndicatorHeight() {
return indicatorHeight;
}
public void setUnderlineColor( int underlineColor ) {
this.underlineColor = underlineColor;
invalidate();
}
public void setUnderlineColorResource( int resId ) {
this.underlineColor = getResources().getColor( resId );
invalidate();
}
public int getUnderlineColor() {
return underlineColor;
}
public void setDividerColor( int dividerColor ) {
this.dividerColor = dividerColor;
invalidate();
}
public void setDividerColorResource( int resId ) {
this.dividerColor = getResources().getColor( resId );
invalidate();
}
public int getDividerColor() {
return dividerColor;
}
public void setUnderlineHeight( int underlineHeightPx ) {
this.underlineHeight = underlineHeightPx;
invalidate();
}
public int getUnderlineHeight() {
return underlineHeight;
}
public void setDividerPadding( int dividerPaddingPx ) {
this.dividerPadding = dividerPaddingPx;
invalidate();
}
public int getDividerPadding() {
return dividerPadding;
}
public void setScrollOffset( int scrollOffsetPx ) {
this.scrollOffset = scrollOffsetPx;
invalidate();
}
public int getScrollOffset() {
return scrollOffset;
}
public void setShouldExpand( boolean shouldExpand ) {
this.shouldExpand = shouldExpand;
notifyDataSetChanged();
}
public boolean getShouldExpand() {
return shouldExpand;
}
public boolean isTextAllCaps() {
return textAllCaps;
}
public void setAllCaps( boolean textAllCaps ) {
this.textAllCaps = textAllCaps;
}
public void setTextSize( int textSizePx ) {
this.tabTextSize = textSizePx;
updateTabStyles();
}
public int getTextSize() {
return tabTextSize;
}
public void setTextColor( int textColor ) {
this.tabTextColor = textColor;
updateTabStyles();
}
public void setTextColorResource( int resId ) {
this.tabTextColor = getResources().getColor( resId );
updateTabStyles();
}
public int getTextColor() {
return tabTextColor;
}
public void setSelectedTextColor( int textColor ) {
this.selectedTabTextColor = textColor;
updateTabStyles();
}
public void setSelectedTextColorResource( int resId ) {
this.selectedTabTextColor = getResources().getColor( resId );
updateTabStyles();
}
public int getSelectedTextColor() {
return selectedTabTextColor;
}
public void setTypeface( Typeface typeface, int style ) {
this.tabTypeface = typeface;
this.tabTypefaceStyle = style;
updateTabStyles();
}
public void setTabBackground( int resId ) {
this.tabBackgroundResId = resId;
updateTabStyles();
}
public int getTabBackground() {
return tabBackgroundResId;
}
public void setTabPaddingLeftRight( int paddingPx ) {
this.tabPadding = paddingPx;
updateTabStyles();
}
public int getTabPaddingLeftRight() {
return tabPadding;
}
@Override
public void onRestoreInstanceState( Parcelable state ) {
SavedState savedState = ( SavedState ) state;
super.onRestoreInstanceState( savedState.getSuperState() );
currentPosition = savedState.currentPosition;
requestLayout();
}
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState( superState );
savedState.currentPosition = currentPosition;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPosition;
public SavedState( Parcelable superState ) {
super( superState );
}
private SavedState( Parcel in ) {
super( in );
currentPosition = in.readInt();
}
@Override
public void writeToParcel( Parcel dest, int flags ) {
super.writeToParcel( dest, flags );
dest.writeInt( currentPosition );
}
public static final Creator< SavedState > CREATOR = new Creator< SavedState >() {
@Override
public SavedState createFromParcel( Parcel in ) {
return new SavedState( in );
}
@Override
public SavedState[] newArray( int size ) {
return new SavedState[size];
}
};
}
}

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="false">
<shape android:shape="rectangle">
<!-- 填充的颜色 -->
<solid android:color="#4DFFFFFF" />
<!-- 设置矩形的四个角为弧形 -->
<!-- android:radius 弧形的半径 -->
<corners android:radius="90px" />
</shape>
</item>
<item android:state_selected="true">
<shape android:shape="rectangle">
<!-- 填充的颜色 -->
<solid android:color="#FFFFFF" />
<!-- 设置矩形的四个角为弧形 -->
<!-- android:radius 弧形的半径 -->
<corners android:radius="90px" />
</shape>
</item>
</selector>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_shortAnimTime">
<item android:state_pressed="true" android:drawable="@android:color/transparent" />
<item android:state_focused="true" android:drawable="@android:color/transparent"/>
<item android:drawable="@android:color/transparent"/>
</selector>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<!-- 填充的颜色 -->
<solid android:color="#409EEA" />
<!-- 设置矩形的四个角为弧形 -->
<!-- android:radius 弧形的半径 -->
<corners android:radius="18dp" />
</shape>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:id="@+id/module_apps_id_indicator_dot"
android:layout_width="@dimen/module_apps_indicator_width"
android:background="@drawable/module_apps_pager_indicator"
android:layout_height="@dimen/module_apps_indicator_height" />
</LinearLayout>

View File

@@ -41,16 +41,13 @@
android:layout_marginTop="@dimen/module_apps_pager_marginTop"
android:overScrollMode="never" />
<com.mogo.module.apps.view.LinePageIndicator
<com.mogo.module.apps.view.PagerSlidingTabStripV2
android:id="@+id/module_apps_id_indicator"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:layout_marginBottom="@dimen/module_apps_indicator_marginBottom"
app:lineWidth="@dimen/module_apps_indicator_width"
app:selectedColor="#ffffffff"
app:strokeWidth="@dimen/module_apps_indicator_height"
app:unselectedColor="#33ffffff" />
app:pstsV2TabPaddingLeftRight="@dimen/module_apps_indicator_interval" />
<ProgressBar
android:id="@+id/module_apps_id_loading"

View File

@@ -9,6 +9,7 @@
<ImageView
android:id="@+id/module_apps_id_app_icon"
android:layout_width="@dimen/module_apps_navigation_icon_width"
android:scaleType="fitXY"
android:layout_height="@dimen/module_apps_navigation_icon_height" />
<TextView

View File

@@ -3,6 +3,7 @@
<dimen name="module_apps_pager_marginTop">117px</dimen>
<dimen name="module_apps_indicator_height">2.7px</dimen>
<dimen name="module_apps_indicator_width">16px</dimen>
<dimen name="module_apps_indicator_interval">2.3px</dimen>
<dimen name="module_apps_indicator_marginBottom">54.9px</dimen>
<dimen name="module_apps_navigation_icon_width">64px</dimen>
<dimen name="module_apps_navigation_icon_height">64px</dimen>

View File

@@ -3,6 +3,7 @@
<dimen name="module_apps_pager_marginTop">260px</dimen>
<dimen name="module_apps_indicator_height">5px</dimen>
<dimen name="module_apps_indicator_width">30px</dimen>
<dimen name="module_apps_indicator_interval">4px</dimen>
<dimen name="module_apps_indicator_marginBottom">103px</dimen>
<dimen name="module_apps_navigation_icon_width">120px</dimen>
<dimen name="module_apps_navigation_icon_height">120px</dimen>

View File

@@ -3,6 +3,7 @@
<dimen name="module_apps_pager_marginTop">260px</dimen>
<dimen name="module_apps_indicator_height">5px</dimen>
<dimen name="module_apps_indicator_width">30px</dimen>
<dimen name="module_apps_indicator_interval">2.3px</dimen>
<dimen name="module_apps_indicator_marginBottom">103px</dimen>
<dimen name="module_apps_navigation_icon_width">120px</dimen>
<dimen name="module_apps_navigation_icon_height">120px</dimen>

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="LinePageIndicator">
<!-- Whether or not the indicators should be centered. -->
<attr name="centered" />
<!-- Color of the unselected lines that represent the pages. -->
<attr name="unselectedColor" />
<!-- Color of the selected line that represents the current page. -->
<attr name="selectedColor" />
<!-- Width of each indicator line. -->
<attr name="lineWidth" format="dimension" />
<!-- Width of each indicator line's stroke. -->
<attr name="strokeWidth" />
<!-- Width of the gap between each indicator line. -->
<attr name="gapWidth" format="dimension" />
<!-- View background -->
<attr name="android:background" />
</declare-styleable>
</resources>

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="card_common_margin_left">@dimen/dp_15</dimen>
<dimen name="default_line_indicator_line_width">12dp</dimen>
<dimen name="default_line_indicator_gap_width">4dp</dimen>
<dimen name="default_line_indicator_stroke_width">1dp</dimen>
<color name="default_line_indicator_selected_color">#FF33B5E5</color>
<color name="default_line_indicator_unselected_color">#FFBBBBBB</color>
<bool name="default_line_indicator_centered">true</bool>
<declare-styleable name="ViewPagerIndicator">
<!-- Style of the circle indicator. -->
<attr name="vpiCirclePageIndicatorStyle" format="reference" />
<!-- Style of the icon indicator's views. -->
<attr name="vpiIconPageIndicatorStyle" format="reference" />
<!-- Style of the line indicator. -->
<attr name="vpiLinePageIndicatorStyle" format="reference" />
<!-- Style of the title indicator. -->
<attr name="vpiTitlePageIndicatorStyle" format="reference" />
<!-- Style of the tab indicator's tabs. -->
<attr name="vpiTabPageIndicatorStyle" format="reference" />
<!-- Style of the underline indicator. -->
<attr name="vpiUnderlinePageIndicatorStyle" format="reference" />
</declare-styleable>
</resources>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="PagerSlidingTabStripV2">
<attr name="pstsV2IndicatorColor" format="color" />
<attr name="pstsV2UnderlineColor" format="color" />
<attr name="pstsV2DividerColor" format="color" />
<attr name="pstsV2IndicatorHeight" format="dimension" />
<attr name="pstsV2UnderlineHeight" format="dimension" />
<attr name="pstsV2DividerPadding" format="dimension" />
<attr name="pstsV2TabPaddingLeftRight" format="dimension" />
<attr name="pstsV2ScrollOffset" format="dimension" />
<attr name="pstsV2TabBackground" format="reference" />
<attr name="pstsV2ShouldExpand" format="boolean" />
<attr name="pstsV2TextAllCaps" format="boolean" />
<attr name="pstsV2SelectedTabTextColor" format="color" />
<attr name="pstsV2TabTextColorValue" format="color" />
<attr name="pstsV2IndicatorMarginBottom" format="dimension" />
<attr name="pstsV2IndicatorMarginLeft" format="dimension" />
<attr name="pstsV2IndicatorMarginRight" format="dimension" />
<attr name="pstsV2IndicatorMode" format="enum">
<enum name="underline" value="-1" />
<enum name="shadow" value="1" />
<enum name="res" value="2" />
</attr>
<attr name="pstsV2IndicatorRes" format="reference" />
</declare-styleable>
</resources>

View File

@@ -37,14 +37,9 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.core:core-ktx:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation rootProject.ext.dependencies.kotlinstdlibjdk7
implementation rootProject.ext.dependencies.androidxappcompat
implementation rootProject.ext.dependencies.androidxccorektx
implementation rootProject.ext.dependencies.androidxconstraintlayout
implementation rootProject.ext.dependencies.arouter
annotationProcessor rootProject.ext.dependencies.aroutercompiler

Binary file not shown.

Before

Width:  |  Height:  |  Size: 403 B

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 B

After

Width:  |  Height:  |  Size: 465 B

View File

@@ -18,6 +18,7 @@
android:paddingLeft="@dimen/module_ext_search_paddingLeft"
android:paddingRight="@dimen/module_ext_search_paddingRight"
android:text="@string/module_map_str_search_hint"
android:textColorHint="#FFFFFF"
android:textColor="#99FFFFFF"
android:textSize="@dimen/module_ext_search_textSize"
app:layout_constraintLeft_toLeftOf="parent"

View File

@@ -92,6 +92,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="/"
android:textSize="@dimen/module_ext_weather_temp_desc_textSize"
android:textColor="#FFFFFF" />
</LinearLayout>

View File

@@ -2,6 +2,7 @@ package com.mogo.module.main;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
@@ -101,6 +102,7 @@ public class MainActivity extends MvpActivity<MainView, MainPresenter> implement
@Override
public void onPageSelected(int position) {
final long start = System.currentTimeMillis();
try {
IMogoModuleProvider provider = mCardModulesAdapter.getProvider(mCurrentPosition);
trackLastCardShowEvent(provider);
@@ -114,10 +116,12 @@ public class MainActivity extends MvpActivity<MainView, MainPresenter> implement
} catch (Exception e) {
e.printStackTrace();
}
Log.i(TAG, "onPageSelected cost " + (System.currentTimeMillis() - start) + "ms");
}
@Override
public void onPageScrollStateChanged(int state) {
final long start = System.currentTimeMillis();
super.onPageScrollStateChanged(state);
if (state == ViewPager.SCROLL_STATE_DRAGGING) {
if (!mCardFlipStatus) {
@@ -143,6 +147,7 @@ public class MainActivity extends MvpActivity<MainView, MainPresenter> implement
} else {
mIsLast = true;
}
Log.i(TAG, "onPageScrollStateChanged cost " + (System.currentTimeMillis() - start) + "ms");
}
/**

View File

@@ -5,6 +5,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.text.TextUtils;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.TextView;
@@ -231,7 +232,7 @@ public class MogoModulesManager implements MogoModulesHandler,
@Override
public void setModuleEnable( String module ) {
final long start1 = System.currentTimeMillis();
// 仅操作上一个模块和当前模块
Iterator< IMogoModuleProvider > iterator = mModuleProviders.values().iterator();
int counter = 0;
@@ -286,6 +287,7 @@ public class MogoModulesManager implements MogoModulesHandler,
mSortedCards.remove( mEnableModuleName );
mSortedCards.add( 0, mEnableModuleName );
SharedPrefsMgr.getInstance( getContext() ).putString( KEY_SORTED_CARD_MODULES, GsonUtil.jsonFromObject( mSortedCards ) );
Log.i(TAG, "enable & disable card cost " + (System.currentTimeMillis() - start1) + "ms");
}
@Override

View File

@@ -45,8 +45,6 @@ dependencies {
implementation rootProject.ext.dependencies.androidxconstraintlayout
implementation rootProject.ext.dependencies.arouter
implementation rootProject.ext.dependencies.room
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
kapt rootProject.ext.dependencies.roomAnnotationProcessor
implementation rootProject.ext.dependencies.roomRxjava
implementation rootProject.ext.dependencies.androidxrecyclerview

View File

@@ -0,0 +1,68 @@
package com.mogo.module.service.datamanager;
import android.text.TextUtils;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.service.MogoServicePaths;
import com.mogo.service.datamanager.IMogoDataChangedListener;
import com.mogo.service.datamanager.IMogoDataManager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* @author congtaowang
* @since 2020-02-11
* <p>
* 描述
*/
public class MogoDataHandler {
private Map< String, List< IMogoDataChangedListener > > mListeners = new HashMap<>();
private MogoDataHandler() {
// private constructor
}
private static final class InstanceHolder {
private static final MogoDataHandler INSTANCE = new MogoDataHandler();
}
public static MogoDataHandler getInstance() {
return InstanceHolder.INSTANCE;
}
public synchronized void registerDataListener( String tag, IMogoDataChangedListener listener ) {
if ( listener == null || TextUtils.isEmpty( tag ) ) {
return;
}
if ( !mListeners.containsKey( tag ) || mListeners.get( tag ) == null ) {
mListeners.put( tag, new ArrayList< IMogoDataChangedListener >() );
}
}
public synchronized void unregisterListener( String tag, IMogoDataChangedListener listener ) {
if ( listener == null || TextUtils.isEmpty( tag ) ) {
return;
}
if ( mListeners.containsKey( tag ) && mListeners.get( tag ) != null ) {
mListeners.get( tag ).remove( listener );
}
}
public void invoke( String tag, List< Object > datums ) {
if ( tag == null ) {
return;
}
Iterator< IMogoDataChangedListener > iterator = mListeners.get( tag ).iterator();
while ( iterator.hasNext() ) {
IMogoDataChangedListener listener = iterator.next();
if ( listener != null ) {
listener.onDataSetChanged( datums );
}
}
}
}

View File

@@ -0,0 +1,33 @@
package com.mogo.module.service.datamanager;
import android.content.Context;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.service.MogoServicePaths;
import com.mogo.service.datamanager.IMogoDataChangedListener;
import com.mogo.service.datamanager.IMogoDataManager;
/**
* @author congtaowang
* @since 2020-02-11
* <p>
* 描述
*/
@Route( path = MogoServicePaths.PATH_DATA_MANAGER )
public class MogoDataManager implements IMogoDataManager {
@Override
public void registerDataListener( String tag, IMogoDataChangedListener listener ) {
MogoDataHandler.getInstance().registerDataListener( tag, listener );
}
@Override
public void unregisterListener( String tag, IMogoDataChangedListener listener ) {
MogoDataHandler.getInstance().unregisterListener( tag, listener );
}
@Override
public void init( Context context ) {
}
}

View File

@@ -32,14 +32,9 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.core:core-ktx:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation rootProject.ext.dependencies.kotlinstdlibjdk7
implementation rootProject.ext.dependencies.androidxappcompat
implementation rootProject.ext.dependencies.androidxccorektx
implementation rootProject.ext.dependencies.androidxconstraintlayout
implementation rootProject.ext.dependencies.arouter
annotationProcessor rootProject.ext.dependencies.aroutercompiler

View File

@@ -1,17 +0,0 @@
package com.example.mogo_module_share
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

View File

@@ -64,10 +64,10 @@ dependencies {
implementation project(':modules:mogo-module-share')
}
implementation 'com.shuyu:gsyVideoPlayer-armv7a:7.1.1'
implementation 'com.shuyu:gsyVideoPlayer-arm64:7.1.1'
implementation 'com.shuyu:gsyVideoPlayer-java:7.1.1'
implementation 'org.greenrobot:eventbus:3.1.1'
implementation rootProject.ext.dependencies.videoarmv7
implementation rootProject.ext.dependencies.videoarm64
implementation rootProject.ext.dependencies.videojava
implementation rootProject.ext.dependencies.eventbus
}
apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()

View File

@@ -66,13 +66,8 @@ class MediaCoverVideoPlayer : StandardGSYVideoPlayer {
return GSYVideoManager.instance()
}
override fun setProgressAndTime(
progress: Int,
secProgress: Int,
currentTime: Int,
totalTime: Int
) {
super.setProgressAndTime(progress, secProgress, currentTime, totalTime)
override fun setProgressAndTime(progress: Int, secProgress: Int, currentTime: Int, totalTime: Int, forceChange: Boolean) {
super.setProgressAndTime(progress, secProgress, currentTime, totalTime, forceChange)
if (progress != 0) {
mProgressBar.progress = progress
}

View File

@@ -45,14 +45,9 @@ class SimpleCoverVideoPlayer : StandardGSYVideoPlayer {
return GSYVideoManager.instance()
}
override fun setProgressAndTime(
progress: Int,
secProgress: Int,
currentTime: Int,
totalTime: Int
) {
super.setProgressAndTime(progress, secProgress, currentTime, totalTime)
Log.e("liyz", "setProgressAndTime progress = $progress --->currentTime = $currentTime --->totalTime = $totalTime")
override fun setProgressAndTime(progress: Int, secProgress: Int, currentTime: Int, totalTime: Int, forceChange: Boolean) {
super.setProgressAndTime(progress, secProgress, currentTime, totalTime, forceChange)
// Log.e("liyz", "setProgressAndTime progress = $progress --->currentTime = $currentTime --->totalTime = $totalTime")
if (progress != 0) {
mProgressBar.progress = progress
}
@@ -79,12 +74,12 @@ class SimpleCoverVideoPlayer : StandardGSYVideoPlayer {
override fun changeUiToCompleteShow() {
super.changeUiToCompleteShow()
// setViewShowState(mBottomContainer, View.INVISIBLE)
mBottomContainer.visibility = View.INVISIBLE
Log.d("liyz", "changeUiToCompleteShow ------------>")
}
override fun hideAllWidget() {
super.hideAllWidget()
Log.d("liyz", "hideAllWidget ------------>")
mBottomContainer.visibility = View.VISIBLE
}

View File

@@ -3,6 +3,7 @@
<item android:id="@android:id/background">
<shape>
<solid android:color="#59000000"/>
<corners android:radius="4dp" />
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
@@ -15,7 +16,7 @@
<item android:id="@android:id/progress">
<clip>
<shape>
<!-- <solid android:color="#66FFFFFF"/>-->
<solid android:color="#FF0000"/>
<corners android:radius="5dp" />
<!--在gradient这里设置不同的颜色就会产生渐变的效果-->
<gradient

View File

@@ -15,7 +15,7 @@
<dimen name="tanlu_module_full_loading_height">96px</dimen>
<dimen name="tanlu_module_full_bottom_height">100px</dimen>
<dimen name="tanlu_module_full_bottom_width">700px</dimen>
<dimen name="tanlu_module_full_bottom_margin">5px</dimen>
<dimen name="tanlu_module_full_bottom_margin">7px</dimen>
<dimen name="tanlu_module_full_top_height">135px</dimen>
<dimen name="tanlu_module_full_back_width">50px</dimen>

View File

@@ -15,7 +15,7 @@
<dimen name="tanlu_module_full_loading_height">96px</dimen>
<dimen name="tanlu_module_full_bottom_height">144px</dimen>
<dimen name="tanlu_module_full_bottom_width">760px</dimen>
<dimen name="tanlu_module_full_bottom_margin">5px</dimen>
<dimen name="tanlu_module_full_bottom_margin">7px</dimen>
<dimen name="tanlu_module_full_top_height">135px</dimen>
<dimen name="tanlu_module_full_back_width">50px</dimen>

View File

@@ -109,5 +109,10 @@ public class MogoServicePaths {
*/
public static final String PATH_SERACH_CENTER = "/searchcenter/api";
/**
* 大而全数据管理中心
*/
public static final String PATH_DATA_MANAGER = "/datamanager/api";
}

View File

@@ -0,0 +1,19 @@
package com.mogo.service.datamanager;
import java.util.List;
/**
* @author congtaowang
* @since 2020-02-11
* <p>
* 描述
*/
public interface IMogoDataChangedListener {
/**
* 大而全数据变化回调
*
* @param datums
*/
void onDataSetChanged( List< Object > datums );
}

View File

@@ -0,0 +1,27 @@
package com.mogo.service.datamanager;
import com.alibaba.android.arouter.facade.template.IProvider;
/**
* @author congtaowang
* @since 2020-02-11
* <p>
* 大而全的数据管理
*/
public interface IMogoDataManager extends IProvider {
/**
* 注册大而全数据变化监听
*
* @param tag 监听模块
* @param listener
*/
void registerDataListener( String tag, IMogoDataChangedListener listener );
/**
* 注销大而全数据变换监听
*
* @param tag
*/
void unregisterListener( String tag , IMogoDataChangedListener listener);
}

View File

@@ -25,6 +25,7 @@ import com.mogo.service.impl.imageloader.glide.transform.GlideCircleBitmapTransf
import com.mogo.service.impl.imageloader.glide.transform.GlideRoundBitmapTransform;
import com.mogo.service.impl.imageloader.glide.utils.DiskLruCacheManager;
import com.mogo.utils.glide.GlideApp;
import com.mogo.utils.logger.Logger;
import java.io.File;
@@ -36,6 +37,8 @@ import java.io.File;
*/
public class GlideImageLoader implements IMogoImageloader {
private static final String TAG = "GlideImageLoader";
private static volatile GlideImageLoader sInstance;
private GlideImageLoader() {
@@ -75,6 +78,8 @@ public class GlideImageLoader implements IMogoImageloader {
@Override
public void displayImage( String url, MogoImageView imageView, int width, int height, final IMogoImageLoaderListener listener ) {
Logger.d(TAG, "url = %s", url);
if ( listener != null ) {
listener.onStart();
}