diff --git a/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_route_fragment.xml b/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_route_fragment.xml index 557740ae89..7a7792bdc1 100644 --- a/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_route_fragment.xml +++ b/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_route_fragment.xml @@ -115,6 +115,8 @@ android:ellipsize="marquee" android:marqueeRepeatLimit="marquee_forever" android:text="----" + app:customGap="0.5" + app:useCustomGap="true" android:textColor="@color/bus_p_line_name_color" android:textSize="@dimen/bus_p_driver_number_plate_size" android:textStyle="bold" diff --git a/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_stations_common_item.xml b/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_stations_common_item.xml index 9416bfb1c8..d33ecffc3a 100644 --- a/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_stations_common_item.xml +++ b/OCH/mogo-och-bus-passenger/src/main/res/layout/bus_p_stations_common_item.xml @@ -18,6 +18,8 @@ android:layout_marginRight="@dimen/dp_60" android:textColor="@color/bus_p_station_txt_color" android:layout_marginLeft="@dimen/dp_90" + app:customGap="0.5" + app:useCustomGap="true" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@+id/bus_p_tag" app:layout_constraintTop_toBottomOf="@+id/bus_p_cur_arrow_bg"/> diff --git a/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/utils/FieldUtils.java b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/utils/FieldUtils.java new file mode 100644 index 0000000000..9dc909d19c --- /dev/null +++ b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/utils/FieldUtils.java @@ -0,0 +1,37 @@ +package com.mogo.och.common.module.utils; + +import android.text.TextUtils; + +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Modifier; + +public class FieldUtils { + + public static Field getDeclaredField(final Class cls, final String fieldName, final + boolean forceAccess) { + if (cls == null || TextUtils.isEmpty(fieldName)) { + return null; + } + try { + // only consider the specified class by using getDeclaredField() + final Field field = cls.getDeclaredField(fieldName); + if (!isAccessible(field)) { + if (forceAccess) { + field.setAccessible(true); + } else { + return null; + } + } + return field; + } catch (final Exception e) { + e.printStackTrace(); + } + return null; + } + + + private static boolean isAccessible(final Member m) { + return m != null && Modifier.isPublic(m.getModifiers()) && !m.isSynthetic(); + } +} \ No newline at end of file diff --git a/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/wigets/MarqueeTextView.java b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/wigets/MarqueeTextView.java index 31c979747d..884d504338 100644 --- a/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/wigets/MarqueeTextView.java +++ b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/wigets/MarqueeTextView.java @@ -1,12 +1,31 @@ package com.mogo.och.common.module.wigets; import android.content.Context; +import android.content.res.TypedArray; import android.util.AttributeSet; import android.view.ViewDebug; +import android.widget.TextView; + +import com.mogo.och.common.module.R; +import com.mogo.och.common.module.utils.FieldUtils; + +import java.lang.reflect.Field; public class MarqueeTextView extends androidx.appcompat.widget.AppCompatTextView{ + /** + * 上一次设置的时间,用于过滤多余操作 + */ + private long mLastSetTime; + /** + * 自定义 gap + */ + private float mCustomGap = 0.3f; + /** + * 是否使用自定义 gap + */ + private boolean mUseCustomGap; public MarqueeTextView(Context context) { this(context, null); @@ -18,6 +37,11 @@ public class MarqueeTextView extends androidx.appcompat.widget.AppCompatTextView public MarqueeTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); + + TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MarqueeTextView); + mCustomGap = typedArray.getFloat(R.styleable.MarqueeTextView_customGap, mCustomGap); + mUseCustomGap = typedArray.getBoolean(R.styleable.MarqueeTextView_useCustomGap, false); + typedArray.recycle(); } @Override @@ -32,4 +56,74 @@ public class MarqueeTextView extends androidx.appcompat.widget.AppCompatTextView return true; } + @Override + public void invalidate() { + reflectToChangeGap(); + + super.invalidate(); + } + + private void reflectToChangeGap() { + if (!mUseCustomGap) { + return; + } + if (System.currentTimeMillis() - mLastSetTime < 1000) { + // 1s 内不重新设置,过滤多余操作 + return; + } + try { + Class marqueClass = null; + Class[] innerClazz = TextView.class.getDeclaredClasses(); + for (Class clazz : innerClazz) { + if ("Marquee".equals(clazz.getSimpleName())) { + marqueClass = clazz; + } + } + + if (marqueClass == null) { + return; + } + + Field field1 = FieldUtils.getDeclaredField(marqueClass, "mGhostStart", true); + + if (field1 == null) { + return; + } + + final int textWidth = getWidth() - getCompoundPaddingLeft() - getCompoundPaddingRight(); + final float lineWidth = getLayout().getLineWidth(0); + final float gap = mCustomGap*textWidth; + float ghostStart = lineWidth - textWidth + gap; + float maxScroll = ghostStart + textWidth; + float ghostOffset = lineWidth + gap; + float maxFadeScroll = ghostStart + lineWidth + lineWidth; + + final Field field = FieldUtils.getDeclaredField(TextView.class, "mMarquee", true); + if (field != null) { + Object mMarque = field.get(this); + if (mMarque != null) { + mLastSetTime = System.currentTimeMillis(); + float mGhostStart = (float) field1.get(mMarque); + if (mGhostStart != ghostStart) { + // 需要设置的 mGhostStart 与当前 ghostStart 不相等时才去设置 + Field field2 = FieldUtils.getDeclaredField(marqueClass, "mMaxScroll", true); + Field field3 = FieldUtils.getDeclaredField(marqueClass, "mGhostOffset", true); + Field field4 = FieldUtils.getDeclaredField(marqueClass, "mMaxFadeScroll", true); + + if (field2 == null || field3 == null || field4 == null) { + return; + } + + field1.set(mMarque, ghostStart); + field2.set(mMarque, maxScroll); + field3.set(mMarque, ghostOffset); + field4.set(mMarque, maxFadeScroll); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } diff --git a/OCH/mogo-och-common-module/src/main/res/values/attrs.xml b/OCH/mogo-och-common-module/src/main/res/values/attrs.xml index 27efdf3802..9043a1d2ad 100644 --- a/OCH/mogo-och-common-module/src/main/res/values/attrs.xml +++ b/OCH/mogo-och-common-module/src/main/res/values/attrs.xml @@ -52,4 +52,9 @@ + + + + + \ No newline at end of file