1.定位的问题

This commit is contained in:
2025-09-26 01:18:18 +08:00
committed by 梁小江
parent a883aa86e5
commit 393c59dd1b
13 changed files with 787 additions and 9 deletions

18
.idea/deploymentTargetSelector.xml generated Normal file
View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetSelector">
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-09-18T12:45:46.137835600Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=6705124a" />
</handle>
</Target>
</DropdownSelection>
<DialogSelection />
</SelectionState>
</selectionStates>
</component>
</project>

View File

@@ -1,8 +1,6 @@
#Wed May 07 09:31:48 CST 2025
#Mon Sep 22 21:05:11 CST 2025
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
#distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.7-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
#distributionUrl=file:///D:/Greadle/gradle-8.10.2-all.zip
distributionUrl=file:///D:/Gradle/gradle-8.10.2-bin.zip
zipStorePath=wrapper/distsl.

View File

@@ -0,0 +1,119 @@
package com.xscm.moduleutil.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import androidx.appcompat.widget.AppCompatImageView;
import com.xscm.moduleutil.R;
public class AvatarWithDecoration extends AppCompatImageView {
// 挂件图片
private Drawable decoration;
// 挂件位置偏移量
private int decorationOffsetX = 0;
private int decorationOffsetY = 0;
// 挂件大小比例(相对于头像)
private float decorationScale = 0.3f;
public AvatarWithDecoration(Context context) {
super(context);
init();
}
public AvatarWithDecoration(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public AvatarWithDecoration(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AvatarWithDecoration);
decoration = a.getDrawable(R.styleable.AvatarWithDecoration_decoration);
decorationScale = a.getFloat(R.styleable.AvatarWithDecoration_decorationScale, 0.3f);
decorationOffsetX = a.getInt(R.styleable.AvatarWithDecoration_decorationOffsetX, 0);
decorationOffsetY = a.getInt(R.styleable.AvatarWithDecoration_decorationOffsetY, 0);
a.recycle();
}
private void init() {
// 可以在这里设置默认的挂件
decoration = getResources().getDrawable(R.mipmap.xlh_image);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 如果有挂件,则绘制挂件
if (decoration != null) {
drawDecoration(canvas);
}
}
private void drawDecoration(Canvas canvas) {
// 获取头像的宽高
int avatarWidth = getWidth();
int avatarHeight = getHeight();
// 计算挂件的大小
int decorationWidth = (int) (avatarWidth * decorationScale);
int decorationHeight = (int) (avatarHeight * decorationScale);
// 计算挂件的位置(右下角)
int left = avatarWidth - decorationWidth + decorationOffsetX;
int top = avatarHeight - decorationHeight + decorationOffsetY;
int right = left + decorationWidth;
int bottom = top + decorationHeight;
// 设置挂件的绘制边界
decoration.setBounds(left, top, right, bottom);
// 绘制挂件
decoration.draw(canvas);
}
/**
* 设置挂件图片
*/
public void setDecoration(Drawable decoration) {
this.decoration = decoration;
invalidate();
}
/**
* 设置挂件图片通过Bitmap
*/
public void setDecoration(Bitmap bitmap) {
if (bitmap != null) {
this.decoration = new BitmapDrawable(getResources(), bitmap);
invalidate();
}
}
/**
* 设置挂件位置偏移量
*/
public void setDecorationOffset(int offsetX, int offsetY) {
this.decorationOffsetX = offsetX;
this.decorationOffsetY = offsetY;
invalidate();
}
/**
* 设置挂件大小比例
*/
public void setDecorationScale(float scale) {
if (scale > 0 && scale <= 1) {
this.decorationScale = scale;
invalidate();
}
}
}

View File

@@ -0,0 +1,373 @@
package com.xscm.moduleutil.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import androidx.annotation.Nullable;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.xscm.moduleutil.R;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class FashionAvatarView extends View {
// 头像相关属性
private Bitmap mAvatarBitmap;
private String mAvatarUrl;
private Drawable mPlaceholderAvatar;
private int mAvatarRadius;
private int mAvatarBorderWidth;
private int mAvatarBorderColor;
// 顶部标签属性
private String mTagText;
private int mTagTextColor;
private float mTagTextSize;
private int mTagBackgroundColor;
private float mTagCornerRadius;
private int mTagPadding;
private int mTagOffsetY; // 标签Y轴偏移量
// 底部文字属性
private String mBottomText;
private int mBottomTextColor;
private float mBottomTextSize;
private int mBottomTextOffsetY; // 底部文字Y轴偏移量
// 爱心装饰属性
private Drawable mHeartIcon;
private int mHeartCount;
private int mHeartSize;
private List<PointF> mHeartPositions = new ArrayList<>();
private Random mRandom = new Random();
// 画笔
private Paint mAvatarPaint;
private Paint mTextPaint;
private Paint mTagBgPaint;
public FashionAvatarView(Context context) {
this(context, null);
}
public FashionAvatarView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public FashionAvatarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttrs(context, attrs);
initPaints();
}
private void initAttrs(Context context, AttributeSet attrs) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.FashionAvatarView);
// 头像属性
mAvatarUrl = ta.getString(R.styleable.FashionAvatarView_avatarUrl);
mPlaceholderAvatar = ta.getDrawable(R.styleable.FashionAvatarView_placeholderAvatar);
mAvatarRadius = ta.getDimensionPixelSize(R.styleable.FashionAvatarView_avatarRadius, dp2px(60));
mAvatarBorderWidth = ta.getDimensionPixelSize(R.styleable.FashionAvatarView_avatarBorderWidth, dp2px(2));
mAvatarBorderColor = ta.getColor(R.styleable.FashionAvatarView_avatarBorderColor, Color.parseColor("#FFD700"));
// 顶部标签属性
mTagText = ta.getString(R.styleable.FashionAvatarView_tagText);
mTagTextColor = ta.getColor(R.styleable.FashionAvatarView_tagTextColor, Color.WHITE);
mTagTextSize = ta.getDimension(R.styleable.FashionAvatarView_tagTextSize, sp2px(12));
mTagBackgroundColor = ta.getColor(R.styleable.FashionAvatarView_tagBackgroundColor, Color.parseColor("#FFA500"));
mTagCornerRadius = ta.getDimension(R.styleable.FashionAvatarView_tagCornerRadius, dp2px(4));
mTagPadding = ta.getDimensionPixelSize(R.styleable.FashionAvatarView_tagPadding, dp2px(4));
mTagOffsetY = ta.getDimensionPixelSize(R.styleable.FashionAvatarView_tagOffsetY, 0);
// 底部文字属性
mBottomText = ta.getString(R.styleable.FashionAvatarView_bottomText);
mBottomTextColor = ta.getColor(R.styleable.FashionAvatarView_bottomTextColor, Color.WHITE);
mBottomTextSize = ta.getDimension(R.styleable.FashionAvatarView_bottomTextSize, sp2px(14));
mBottomTextOffsetY = ta.getDimensionPixelSize(R.styleable.FashionAvatarView_bottomTextOffsetY, dp2px(10));
// 爱心装饰属性
mHeartIcon = ta.getDrawable(R.styleable.FashionAvatarView_heartIcon);
if (mHeartIcon == null) {
try {
mHeartIcon = context.getResources().getDrawable(R.mipmap.xlh_image);
} catch (Exception e) {
e.printStackTrace();
}
}
mHeartCount = ta.getInt(R.styleable.FashionAvatarView_heartCount, 6);
mHeartSize = ta.getDimensionPixelSize(R.styleable.FashionAvatarView_heartSize, dp2px(16));
ta.recycle();
// 加载头像
if (mAvatarUrl != null && !mAvatarUrl.isEmpty()) {
loadAvatarFromNetwork();
} else if (mPlaceholderAvatar != null) {
mAvatarBitmap = drawableToBitmap(mPlaceholderAvatar);
}
}
private void initPaints() {
// 头像画笔
mAvatarPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mAvatarPaint.setDither(true);
// 文字画笔
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setTextAlign(Paint.Align.CENTER);
// 标签背景画笔
mTagBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTagBgPaint.setColor(mTagBackgroundColor);
}
private void loadAvatarFromNetwork() {
Glide.with(this)
.asBitmap()
.load(mAvatarUrl)
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
mAvatarBitmap = resource;
invalidate();
}
@Override
public void onLoadFailed(@Nullable Drawable errorDrawable) {
super.onLoadFailed(errorDrawable);
if (mPlaceholderAvatar != null) {
mAvatarBitmap = drawableToBitmap(mPlaceholderAvatar);
}
invalidate();
}
});
}
private Bitmap drawableToBitmap(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
if (drawable == null) {
return null;
}
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
if (width <= 0) width = mAvatarRadius * 2;
if (height <= 0) height = mAvatarRadius * 2;
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
private void initHeartPositions() {
mHeartPositions.clear();
if (mHeartIcon == null || mHeartCount <= 0 || mHeartSize <= 0) {
return;
}
int centerX = getWidth() / 2;
int centerY = getAvatarCenterY();
// 爱心围绕的半径,比头像大一些
int radius = mAvatarRadius + mAvatarBorderWidth + mHeartSize / 2;
for (int i = 0; i < mHeartCount; i++) {
// 随机分布在头像周围
double angle = 2 * Math.PI * mRandom.nextDouble();
// 稍微随机调整距离,让分布更自然
float distanceFactor = 0.8f + mRandom.nextFloat() * 0.4f;
float x = (float) (centerX + radius * distanceFactor * Math.cos(angle));
float y = (float) (centerY + radius * distanceFactor * Math.sin(angle));
mHeartPositions.add(new PointF(x, y));
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// 计算宽度:直径 + 左右可能的爱心空间
int width = 2 * (mAvatarRadius + mAvatarBorderWidth + mHeartSize / 2);
// 计算高度:头像直径 + 标签高度 + 底部文字高度 + 间距
int tagHeight = (int) (mTagTextSize + mTagPadding * 2);
int bottomTextHeight = (int) mBottomTextSize;
int height = 2 * (mAvatarRadius + mAvatarBorderWidth)
+ tagHeight / 2 // 标签一半在头像内
+ bottomTextHeight + mBottomTextOffsetY
+ dp2px(10);
setMeasuredDimension(resolveSize(width, widthMeasureSpec),
resolveSize(height, heightMeasureSpec));
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// 视图大小确定后计算爱心位置
initHeartPositions();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (getWidth() == 0 || getHeight() == 0) {
return;
}
int centerX = getWidth() / 2;
int avatarCenterY = getAvatarCenterY();
// 1. 绘制爱心装饰
drawHearts(canvas);
// 2. 绘制头像边框
mAvatarPaint.setColor(mAvatarBorderColor);
mAvatarPaint.setStyle(Paint.Style.FILL);
canvas.drawCircle(centerX, avatarCenterY, mAvatarRadius + mAvatarBorderWidth, mAvatarPaint);
// 3. 绘制头像
if (mAvatarBitmap != null) {
mAvatarPaint.setShader(new BitmapShader(mAvatarBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
canvas.drawCircle(centerX, avatarCenterY, mAvatarRadius, mAvatarPaint);
mAvatarPaint.setShader(null);
}
// 4. 绘制顶部标签
drawTag(canvas, centerX, avatarCenterY);
// 5. 绘制底部文字
drawBottomText(canvas, centerX);
}
private int getAvatarCenterY() {
// 计算头像中心Y坐标考虑标签的高度
int tagHeight = (int) (mTagTextSize + mTagPadding * 2);
return mAvatarRadius + mAvatarBorderWidth + tagHeight / 2 + mTagOffsetY;
}
private void drawHearts(Canvas canvas) {
if (mHeartIcon == null || mHeartPositions.isEmpty()) {
return;
}
canvas.save();
for (PointF point : mHeartPositions) {
int left = (int) (point.x - mHeartSize / 2);
int top = (int) (point.y - mHeartSize / 2);
int right = left + mHeartSize;
int bottom = top + mHeartSize;
// 只绘制在视图范围内的爱心
if (right > 0 && bottom > 0 && left < getWidth() && top < getHeight()) {
mHeartIcon.setBounds(left, top, right, bottom);
mHeartIcon.draw(canvas);
}
}
canvas.restore();
}
private void drawTag(Canvas canvas, int centerX, int avatarCenterY) {
if (mTagText == null || mTagText.isEmpty()) {
return;
}
// 计算标签文字宽度
mTextPaint.setTextSize(mTagTextSize);
float textWidth = mTextPaint.measureText(mTagText);
// 计算标签背景矩形
float tagLeft = centerX - textWidth / 2 - mTagPadding;
float tagRight = centerX + textWidth / 2 + mTagPadding;
// 标签底部与头像顶部对齐
float tagBottom = avatarCenterY - mAvatarRadius - mAvatarBorderWidth;
float tagTop = tagBottom - mTagTextSize - mTagPadding * 2;
RectF tagRect = new RectF(tagLeft, tagTop, tagRight, tagBottom);
// 绘制标签背景
canvas.drawRoundRect(tagRect, mTagCornerRadius, mTagCornerRadius, mTagBgPaint);
// 绘制标签文字
mTextPaint.setColor(mTagTextColor);
Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
float baseLineY = tagBottom - mTagPadding - fontMetrics.bottom;
canvas.drawText(mTagText, centerX, baseLineY, mTextPaint);
}
private void drawBottomText(Canvas canvas, int centerX) {
if (mBottomText == null || mBottomText.isEmpty()) {
return;
}
// 计算文字位置:头像底部下方
int textY = getAvatarCenterY() + mAvatarRadius + mAvatarBorderWidth + mBottomTextOffsetY;
mTextPaint.setColor(mBottomTextColor);
mTextPaint.setTextSize(mBottomTextSize);
Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
float baseLineY = textY - fontMetrics.top;
canvas.drawText(mBottomText, centerX, baseLineY, mTextPaint);
}
// dp转px
private int dp2px(float dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
getResources().getDisplayMetrics());
}
// sp转px
private float sp2px(float sp) {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp,
getResources().getDisplayMetrics());
}
// 设置器方法
public void setAvatarUrl(String url) {
this.mAvatarUrl = url;
loadAvatarFromNetwork();
}
public void setTagText(String text) {
this.mTagText = text;
invalidate();
}
public void setBottomText(String text) {
this.mBottomText = text;
invalidate();
}
public void setHeartIcon(Drawable heartIcon) {
this.mHeartIcon = heartIcon;
initHeartPositions();
invalidate();
}
}

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 背景颜色,与原代码中的#8D6F28保持一致 -->
<solid android:color="#8D6F28" />
<!-- 圆角半径,可以根据需要调整大小 -->
<corners android:radius="@dimen/dp_5" />
<!-- 可选:添加内边距,让文字与边框有一定距离 -->
<padding
android:left="@dimen/dp_2"
android:right="@dimen/dp_2"
android:top="@dimen/dp_2"
android:bottom="@dimen/dp_2" />
</shape>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 背景颜色,与原代码中的#8D6F28保持一致 -->
<solid android:color="#906C49E4" />
<!-- 圆角半径,可以根据需要调整大小 -->
<corners android:radius="@dimen/dp_5" />
<!-- 可选:添加内边距,让文字与边框有一定距离 -->
<padding
android:left="@dimen/dp_2"
android:right="@dimen/dp_2"
android:top="@dimen/dp_2"
android:bottom="@dimen/dp_2" />
</shape>

View File

@@ -62,6 +62,7 @@
app:layout_constraintTop_toBottomOf="@+id/tv_gz" />
<TextView
android:visibility="gone"
android:id="@+id/tv_time1"
android:layout_width="@dimen/dp_18"
android:layout_height="@dimen/dp_28"
@@ -76,6 +77,7 @@
tools:text="1" />
<TextView
android:visibility="gone"
android:id="@+id/tv_time2"
android:layout_width="@dimen/dp_18"
android:layout_height="@dimen/dp_28"
@@ -90,6 +92,7 @@
tools:text="3" />
<TextView
android:visibility="gone"
android:id="@+id/tv_time_m"
android:layout_width="@dimen/dp_18"
android:layout_height="@dimen/dp_28"
@@ -109,6 +112,7 @@
android:layout_marginStart="@dimen/dp_5"
android:background="@mipmap/time_b"
android:gravity="center"
android:visibility="gone"
android:textColor="#00F3D3"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/tv_bd"
@@ -117,6 +121,7 @@
tools:text="1" />
<TextView
android:visibility="gone"
android:id="@+id/tv_time4"
android:layout_width="@dimen/dp_18"
android:layout_height="@dimen/dp_28"
@@ -128,16 +133,162 @@
app:layout_constraintBottom_toBottomOf="@+id/tv_bd"
app:layout_constraintStart_toEndOf="@+id/tv_time3"
app:layout_constraintTop_toTopOf="@+id/tv_bd"
tools:text="8" />
<LinearLayout
android:layout_marginTop="@dimen/dp_5"
android:layout_marginLeft="@dimen/dp_15"
app:layout_constraintTop_toBottomOf="@+id/tv_jc"
app:layout_constraintLeft_toRightOf="@+id/tv_time4"
android:id="@+id/gift_l4"
android:layout_width="@dimen/dp_56"
android:layout_height="@dimen/dp_73"
android:orientation="vertical"
/>
<com.xscm.moduleutil.widget.GifAvatarOvalView
android:id="@+id/iv_homeowner_bg"
android:background="@color/_000000"
android:layout_width="@dimen/dp_40"
android:layout_height="@dimen/dp_58"
app:layout_constraintStart_toStartOf="@+id/gift_l4"
app:layout_constraintEnd_toEndOf="@+id/gift_l4"
app:layout_constraintTop_toTopOf="@+id/gift_l4"
android:layout_marginTop="@dimen/dp_2"
android:scaleType="fitCenter"/>
<ImageView
android:layout_width="@dimen/dp_60"
android:layout_height="@dimen/dp_58"
app:layout_constraintStart_toStartOf="@+id/gift_l4"
app:layout_constraintEnd_toEndOf="@+id/gift_l4"
app:layout_constraintTop_toTopOf="@+id/gift_l4"
android:layout_marginBottom="@dimen/dp_2"
android:src="@mipmap/xlh_image"
android:scaleType="fitCenter"/>
<TextView
android:id="@+id/tv_homeowner_name"
android:layout_width="wrap_content"
android:layout_height="@dimen/dp_14"
app:layout_constraintStart_toStartOf="@+id/gift_l4"
app:layout_constraintEnd_toEndOf="@+id/gift_l4"
app:layout_constraintBottom_toBottomOf="@+id/gift_l4"
tools:text="时尚的金针菇"
android:gravity="center"
android:textColor="@color/white"
android:textSize="@dimen/sp_10"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_35"
android:background="@drawable/bg_round_corner"
android:text="房主"
android:textColor="#FFE554"
android:textSize="@dimen/sp_12"
app:layout_constraintLeft_toLeftOf="@+id/iv_homeowner_bg"
app:layout_constraintRight_toRightOf="@+id/iv_homeowner_bg"
app:layout_constraintTop_toTopOf="@+id/iv_homeowner_bg" />
<androidx.constraintlayout.widget.ConstraintLayout
android:visibility="gone"
android:layout_marginTop="@dimen/dp_21"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginLeft="@dimen/dp_40"
app:layout_constraintTop_toBottomOf="@+id/tv_homeowner_name"
android:id="@+id/gift_l5"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.xscm.moduleutil.widget.GifAvatarOvalView
app:layout_constraintRight_toRightOf="parent"
android:background="@color/read_dot_bg"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:id="@+id/iv_lucky_person"
android:layout_width="@dimen/dp_64"
android:layout_height="@dimen/dp_80"
android:layout_marginTop="@dimen/dp_2"
android:scaleType="fitCenter"/>
<ImageView
app:layout_constraintRight_toRightOf="@+id/iv_lucky_person"
app:layout_constraintBottom_toBottomOf="@+id/iv_lucky_person"
app:layout_constraintTop_toTopOf="@+id/iv_lucky_person"
app:layout_constraintLeft_toLeftOf="@+id/iv_lucky_person"
android:layout_width="@dimen/dp_94"
android:layout_height="@dimen/dp_90"
android:layout_marginBottom="@dimen/dp_2"
android:src="@mipmap/xlh_image"
android:scaleType="fitCenter"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_65"
android:background="@drawable/bg_round_corner"
android:text="幸运者"
android:textColor="@color/white"
android:textSize="@dimen/sp_12"
app:layout_constraintLeft_toLeftOf="@+id/iv_lucky_person"
app:layout_constraintRight_toRightOf="@+id/iv_lucky_person"
app:layout_constraintTop_toTopOf="@+id/iv_lucky_person" />
<TextView
android:layout_marginTop="@dimen/dp_23"
android:text="烟花易冷"
android:textColor="@color/white"
android:gravity="center"
app:layout_constraintRight_toRightOf="@+id/iv_lucky_person"
app:layout_constraintLeft_toLeftOf="@+id/iv_lucky_person"
app:layout_constraintTop_toBottomOf="@+id/iv_lucky_person"
android:layout_width="0dp"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
app:layout_constraintRight_toLeftOf="@+id/tv_gz"
app:layout_constraintTop_toTopOf="@+id/iv_homeowner_bg"
android:layout_width="wrap_content"
android:layout_marginRight="@dimen/dp_46"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv_iv_bg"
android:layout_width="@dimen/dp_36"
android:layout_height="@dimen/dp_36"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:src="@mipmap/ic_launcher"
android:scaleType="fitCenter"/>
<ImageView
android:id="@+id/iv_bg"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="@dimen/dp_48"
android:background="@mipmap/xlh_g_2"
android:layout_height="@dimen/dp_60"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:visibility="gone"
android:id="@+id/cl_gift"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_195"
android:layout_marginTop="@dimen/dp_10"
app:layout_constraintEnd_toEndOf="parent"
android:background="@mipmap/tour_zj_bj"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_bd">
@@ -281,7 +432,7 @@
android:layout_marginBottom="@dimen/dp_15"
android:orientation="horizontal"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintTop_toBottomOf="@+id/cl_gift"
app:layout_constraintTop_toBottomOf="@+id/gift_l5"
app:layout_constraintBottom_toTopOf="@+id/exchange_layout"
/>
@@ -325,6 +476,7 @@
app:layout_constraintEnd_toStartOf="@+id/tv_option"
app:layout_constraintTop_toTopOf="@+id/exchange_layout"
app:layout_constraintBottom_toBottomOf="@+id/exchange_layout"
android:visibility="gone"
/>
<LinearLayout
android:id="@+id/exchange_layout"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

View File

@@ -0,0 +1,38 @@
<resources>
<declare-styleable name="FashionAvatarView">
<!-- 头像相关属性 -->
<attr name="avatarUrl" format="string" />
<attr name="placeholderAvatar" format="reference" />
<attr name="avatarRadius" format="dimension" />
<attr name="avatarBorderWidth" format="dimension" />
<attr name="avatarBorderColor" format="color" />
<!-- 顶部标签相关属性 -->
<attr name="tagText" format="string" />
<attr name="tagTextColor" format="color" />
<attr name="tagTextSize" format="dimension" />
<attr name="tagBackgroundColor" format="color" />
<attr name="tagCornerRadius" format="dimension" />
<attr name="tagPadding" format="dimension" />
<attr name="tagOffsetY" format="dimension" />
<!-- 底部文字相关属性 -->
<attr name="bottomText" format="string" />
<attr name="bottomTextColor" format="color" />
<attr name="bottomTextSize" format="dimension" />
<attr name="bottomTextOffsetY" format="dimension" />
<!-- 爱心装饰相关属性 -->
<attr name="heartIcon" format="reference" />
<attr name="heartCount" format="integer" />
<attr name="heartSize" format="dimension" />
</declare-styleable>
<declare-styleable name="AvatarWithDecoration">
<attr name="decoration" format="reference" />
<attr name="decorationScale" format="float" />
<attr name="decorationOffsetX" format="integer" />
<attr name="decorationOffsetY" format="integer" />
</declare-styleable>
</resources>

View File

@@ -482,7 +482,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:visibility="visible" />
<!--https://tmd.xscmmidi.site/data/avatar/head_pic.png-->
<com.xscm.moduleutil.widget.DropViewRoom
android:id="@+id/xlh_rk"
android:layout_width="wrap_content"
@@ -520,7 +520,33 @@
</com.xscm.moduleutil.widget.DropViewRoom>
<com.xscm.moduleutil.view.FashionAvatarView
android:layout_marginTop="@dimen/dp_200"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:id="@+id/fashionAvatar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:avatarUrl="https://tmd.xscmmidi.site/data/avatar/head_pic.png"
app:avatarRadius="60dp"
app:avatarBorderWidth="3dp"
app:avatarBorderColor="#FFD700"
app:tagText="房主"
app:tagTextColor="#FFFFFF"
app:tagTextSize="12sp"
app:tagBackgroundColor="#FFA500"
app:tagCornerRadius="4dp"
app:tagPadding="4dp"
app:bottomText="时尚的金针菇"
app:bottomTextColor="#FFFFFF"
app:bottomTextSize="14sp"
app:bottomTextOffsetY="10dp"
app:heartIcon="@mipmap/xlh_image"
app:heartCount="6"
app:heartSize="16dp" />
<com.xscm.moduleutil.widget.floatingView.Floa
android:id="@+id/flaoat"
android:layout_width="@dimen/dp_240"

View File

@@ -0,0 +1,25 @@
package com.example.modulevoice.view;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.TextView;
public class MarqueeTextView extends androidx.appcompat.widget.AppCompatTextView {
public MarqueeTextView(Context context) {
super(context);
}
public MarqueeTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MarqueeTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
// 始终返回true确保能获取焦点
@Override
public boolean isFocused() {
return true;
}
}

View File

@@ -58,7 +58,6 @@
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
app:layout_constraintBottom_toBottomOf="@+id/view_num_bg"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/view_num_bg"