From 8533a83c9a657b4888ea755d96b8743e722a4890 Mon Sep 17 00:00:00 2001 From: yangyxd Date: Fri, 6 Mar 2020 13:12:16 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BE=8E=E5=8C=96=E4=B9=A6=E8=AF=A6=E6=83=85?= =?UTF-8?q?=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ui/book/info/BookInfoActivity.kt | 2 +- .../java/io/legado/app/ui/widget/ArcView.java | 93 ++++ .../legado/app/ui/widget/ScrollTextView.java | 103 ++++ .../main/res/layout/activity_book_info.xml | 456 +++++++++++------- app/src/main/res/layout/item_search.xml | 1 + app/src/main/res/values/strings_yxd.xml | 9 + 6 files changed, 489 insertions(+), 175 deletions(-) create mode 100644 app/src/main/java/io/legado/app/ui/widget/ArcView.java create mode 100644 app/src/main/java/io/legado/app/ui/widget/ScrollTextView.java create mode 100644 app/src/main/res/values/strings_yxd.xml diff --git a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt index 1deccd667..93ef39f65 100644 --- a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt @@ -55,7 +55,7 @@ class BookInfoActivity : override fun onActivityCreated(savedInstanceState: Bundle?) { setSupportActionBar(toolbar) supportActionBar?.setDisplayHomeAsUpEnabled(true) - tv_intro.movementMethod = ScrollingMovementMethod.getInstance() + // tv_intro.movementMethod = ScrollingMovementMethod.getInstance() viewModel.bookData.observe(this, Observer { showBook(it) }) viewModel.chapterListData.observe(this, Observer { upLoading(false, it) }) viewModel.initData(intent) diff --git a/app/src/main/java/io/legado/app/ui/widget/ArcView.java b/app/src/main/java/io/legado/app/ui/widget/ArcView.java new file mode 100644 index 000000000..8e6e849ae --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/widget/ArcView.java @@ -0,0 +1,93 @@ +package io.legado.app.ui.widget; + +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.util.AttributeSet; +import android.view.View; +import io.legado.app.R; +import androidx.annotation.Nullable; + +public class ArcView extends View { + private int mWidth; + private int mHeight; + /** + * 弧形高度 + */ + private int mArcHeight; + /** + * 背景颜色 + */ + private int mBgColor; + private Paint mPaint; + private boolean mDirectionTop; + private Context mContext; + + public ArcView(Context context) { + this(context, null); + } + + public ArcView(Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public ArcView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + + TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ArcView); + mArcHeight = typedArray.getDimensionPixelSize(R.styleable.ArcView_arcHeight, 0); + mBgColor = typedArray.getColor(R.styleable.ArcView_bgColor, Color.parseColor("#303F9F")); + mDirectionTop = typedArray.getBoolean(R.styleable.ArcView_arcDirectionTop, false); + mContext = context; + mPaint = new Paint(); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + mPaint.setStyle(Paint.Style.FILL); + mPaint.setColor(mBgColor); + + if (mDirectionTop) { + Rect rect = new Rect(0, mArcHeight, mWidth, mHeight); + canvas.drawRect(rect, mPaint); + + + Path path = new Path(); + path.moveTo(0, mArcHeight); + path.quadTo(mWidth / 2, 0, mWidth, mArcHeight); + canvas.drawPath(path, mPaint); + } else { + Rect rect = new Rect(0, 0, mWidth, mHeight - mArcHeight); + canvas.drawRect(rect, mPaint); + + + Path path = new Path(); + path.moveTo(0, mHeight - mArcHeight); + path.quadTo(mWidth / 2, mHeight, mWidth, mHeight - mArcHeight); + canvas.drawPath(path, mPaint); + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + int widthSize = MeasureSpec.getSize(widthMeasureSpec); + int widthMode = MeasureSpec.getMode(widthMeasureSpec); + int heightSize = MeasureSpec.getSize(heightMeasureSpec); + int heightMode = MeasureSpec.getMode(heightMeasureSpec); + + if (widthMode == MeasureSpec.EXACTLY) { + mWidth = widthSize; + } + if (heightMode == MeasureSpec.EXACTLY) { + mHeight = heightSize; + } + setMeasuredDimension(mWidth, mHeight); + } +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/widget/ScrollTextView.java b/app/src/main/java/io/legado/app/ui/widget/ScrollTextView.java new file mode 100644 index 000000000..7fc1b7a5b --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/widget/ScrollTextView.java @@ -0,0 +1,103 @@ +package io.legado.app.ui.widget; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.text.Layout; +import android.util.AttributeSet; +import android.view.MotionEvent; + +import androidx.appcompat.widget.AppCompatTextView; + +public class ScrollTextView extends AppCompatTextView { + + //滑动距离的最大边界 + private int mOffsetHeight; + + //是否到顶或者到底的标志 + private boolean mBottomFlag = false; + + + public ScrollTextView(Context context) { + super(context); + } + + public ScrollTextView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public ScrollTextView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + initOffsetHeight(); + } + + @Override + protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) { + super.onTextChanged(text, start, lengthBefore, lengthAfter); + initOffsetHeight(); + } + + private void initOffsetHeight() { + int paddingTop; + int paddingBottom; + int mHeight; + int mLayoutHeight; + + //获得内容面板 + Layout mLayout = getLayout(); + if (mLayout == null) return; + //获得内容面板的高度 + mLayoutHeight = mLayout.getHeight(); + //获取上内边距 + paddingTop = getTotalPaddingTop(); + //获取下内边距 + paddingBottom = getTotalPaddingBottom(); + + //获得控件的实际高度 + mHeight = getMeasuredHeight(); + + //计算滑动距离的边界 + mOffsetHeight = mLayoutHeight + paddingTop + paddingBottom - mHeight; + if (mOffsetHeight <= 0) { + scrollTo(0, 0); + } + } + + @Override + public boolean dispatchTouchEvent(MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + //如果是新的按下事件,则对mBottomFlag重新初始化 + mBottomFlag = mOffsetHeight <= 0; + } + //如果已经不要这次事件,则传出取消的信号,这里的作用不大 + if (mBottomFlag) { + event.setAction(MotionEvent.ACTION_CANCEL); + } + return super.dispatchTouchEvent(event); + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouchEvent(MotionEvent event) { + boolean result = super.onTouchEvent(event); + //如果是需要拦截,则再拦截,这个方法会在onScrollChanged方法之后再调用一次 + if (!mBottomFlag) + getParent().requestDisallowInterceptTouchEvent(true); + return result; + } + + @Override + protected void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) { + super.onScrollChanged(horiz, vert, oldHoriz, oldVert); + if (vert == mOffsetHeight || vert == 0) { + //这里触发父布局或祖父布局的滑动事件 + getParent().requestDisallowInterceptTouchEvent(false); + mBottomFlag = true; + } + } + +} diff --git a/app/src/main/res/layout/activity_book_info.xml b/app/src/main/res/layout/activity_book_info.xml index 693fb53a1..96ea949e6 100644 --- a/app/src/main/res/layout/activity_book_info.xml +++ b/app/src/main/res/layout/activity_book_info.xml @@ -9,227 +9,335 @@ - + android:orientation="vertical"> - - - + + + + + + + + + + + + + + android:paddingLeft="10dp" + android:paddingTop="8dp" + android:paddingRight="10dp" + android:paddingBottom="3dp"> + android:text="@string/book_name" + android:textColor="@color/tv_text_default" + android:textSize="18sp" + tools:ignore="RtlHardcoded" /> - + android:layout_gravity="center" + android:gravity="center" + android:visibility="gone" /> - + + + android:scrollbarStyle="outsideInset" + android:scrollbars="vertical" + android:fillViewport="true" + android:fitsSystemWindows="false" + android:focusable="true" > - + - + - - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + + + + + + android:background="@color/background" + android:orientation="vertical" + android:paddingTop="12dp" + android:paddingBottom="12dp" + app:layout_constraintBottom_toTopOf="@+id/fl_action" + app:layout_constraintTop_toBottomOf="@+id/view_info"> - + + + + + + + android:layout_height="1px" + android:background="@color/bg_divider_line" /> - + - + - - - + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_search.xml b/app/src/main/res/layout/item_search.xml index 73154072b..78e5a44da 100644 --- a/app/src/main/res/layout/item_search.xml +++ b/app/src/main/res/layout/item_search.xml @@ -43,6 +43,7 @@ android:layout_width="0dp" android:layout_height="0dp" android:orientation="vertical" + android:layout_marginTop="8dp" app:layout_constraintBottom_toBottomOf="@id/iv_cover" app:layout_constraintLeft_toLeftOf="@+id/tv_name" app:layout_constraintRight_toRightOf="@id/tv_name" diff --git a/app/src/main/res/values/strings_yxd.xml b/app/src/main/res/values/strings_yxd.xml new file mode 100644 index 000000000..d1ca165ed --- /dev/null +++ b/app/src/main/res/values/strings_yxd.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file