UI界面的样式的修改

This commit is contained in:
ShiQi 2025-12-19 10:50:13 +08:00
parent cb3bfe7dc1
commit 0a3836a0cb
12 changed files with 742 additions and 70 deletions

View File

@ -1,6 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<application
android:allowBackup="true"
@ -67,6 +68,10 @@
android:name="com.example.livestreaming.ProfileActivity"
android:exported="false" />
<activity
android:name="com.example.livestreaming.UserProfileReadOnlyActivity"
android:exported="false" />
<activity
android:name="com.example.livestreaming.WishTreeActivity"
android:exported="false" />

View File

@ -1,12 +1,15 @@
package com.example.livestreaming;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.widget.Toast;
import androidx.core.content.ContextCompat;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;
import androidx.activity.result.ActivityResultLauncher;
@ -30,11 +33,14 @@ public class EditProfileActivity extends AppCompatActivity {
private static final String KEY_GENDER = "profile_gender";
private static final String KEY_LOCATION = "profile_location";
private static final String BIO_HINT_TEXT = "填写个人签名更容易获得关注,点击此处添加";
private Uri selectedAvatarUri = null;
private Uri pendingCameraUri = null;
private ActivityResultLauncher<String> pickImageLauncher;
private ActivityResultLauncher<Uri> takePictureLauncher;
private ActivityResultLauncher<String> requestCameraPermissionLauncher;
public static void start(Context context) {
Intent intent = new Intent(context, EditProfileActivity.class);
@ -60,6 +66,16 @@ public class EditProfileActivity extends AppCompatActivity {
Glide.with(this).load(pendingCameraUri).circleCrop().into(binding.avatarPreview);
});
requestCameraPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(), granted -> {
if (!granted) {
Toast.makeText(this, "需要相机权限才能拍照", Toast.LENGTH_SHORT).show();
pendingCameraUri = null;
return;
}
if (pendingCameraUri == null) return;
takePictureLauncher.launch(pendingCameraUri);
});
binding.backButton.setOnClickListener(v -> finish());
binding.cancelButton.setOnClickListener(v -> finish());
@ -84,7 +100,7 @@ public class EditProfileActivity extends AppCompatActivity {
.putString(KEY_NAME, name)
.apply();
if (TextUtils.isEmpty(bio)) {
if (TextUtils.isEmpty(bio) || BIO_HINT_TEXT.equals(bio)) {
getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().remove(KEY_BIO).apply();
} else {
getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().putString(KEY_BIO, bio).apply();
@ -125,7 +141,11 @@ public class EditProfileActivity extends AppCompatActivity {
String avatarUri = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_AVATAR_URI, null);
binding.inputName.setText(name);
binding.inputBio.setText(bio);
if (!TextUtils.isEmpty(bio) && !BIO_HINT_TEXT.equals(bio)) {
binding.inputBio.setText(bio);
} else {
binding.inputBio.setText("");
}
binding.inputBirthday.setText(birthday);
binding.inputGender.setText(gender);
binding.inputLocation.setText(location);
@ -155,7 +175,7 @@ public class EditProfileActivity extends AppCompatActivity {
Uri uri = createTempCameraUri();
if (uri == null) return;
pendingCameraUri = uri;
takePictureLauncher.launch(uri);
ensureCameraPermissionAndTakePhoto();
});
cancel.setOnClickListener(v -> dialog.dismiss());
@ -163,6 +183,15 @@ public class EditProfileActivity extends AppCompatActivity {
dialog.show();
}
private void ensureCameraPermissionAndTakePhoto() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
if (pendingCameraUri == null) return;
takePictureLauncher.launch(pendingCameraUri);
return;
}
requestCameraPermissionLauncher.launch(Manifest.permission.CAMERA);
}
private Uri createTempCameraUri() {
try {
File dir = new File(getCacheDir(), "images");

View File

@ -2,8 +2,16 @@ package com.example.livestreaming;
import android.content.Intent;
import android.os.Bundle;
import android.animation.ValueAnimator;
import android.os.Handler;
import android.os.Looper;
import android.view.HapticFeedbackConstants;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.view.animation.OvershootInterpolator;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintSet;
import com.example.livestreaming.databinding.ActivityFishPondBinding;
import com.google.android.material.bottomnavigation.BottomNavigationView;
@ -12,12 +20,59 @@ public class FishPondActivity extends AppCompatActivity {
private ActivityFishPondBinding binding;
private static class OrbitUserData {
final String id;
final String name;
final String location;
final String bio;
final int avatarRes;
OrbitUserData(String id, String name, String location, String bio, int avatarRes) {
this.id = id;
this.name = name;
this.location = location;
this.bio = bio;
this.avatarRes = avatarRes;
}
}
private OrbitUserData userTop;
private OrbitUserData userRight;
private OrbitUserData userBottomRight;
private OrbitUserData userBottomCenter;
private OrbitUserData userBottomLeft;
private OrbitUserData userLeft;
private ValueAnimator orbitAnimator;
private int orbitRadiusPx = 0;
private float orbitAngleOffset = 0f;
private final Handler uiHandler = new Handler(Looper.getMainLooper());
private final Runnable pulseRunnable = new Runnable() {
@Override
public void run() {
if (binding == null) return;
View v = pickRandomOrbitUserView();
if (v != null) playBreathingPulse(v);
uiHandler.postDelayed(this, 1400L);
}
};
// base angles for a regular hexagon (clockwise)
private static final float[] ORBIT_BASE_ANGLES = new float[] { 270f, 330f, 30f, 90f, 150f, 210f };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityFishPondBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setupOrbitUserInteractions();
setupCenterRefresh();
binding.orbitContainer.post(this::updateOrbitLayout);
refreshUsers();
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
bottomNavigation.setSelectedItemId(R.id.nav_friends);
bottomNavigation.setOnItemSelectedListener(item -> {
@ -46,11 +101,248 @@ public class FishPondActivity extends AppCompatActivity {
});
}
private void setupCenterRefresh() {
if (binding == null) return;
binding.centerButton.setOnClickListener(v -> {
v.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
v.animate().cancel();
v.animate()
.rotationBy(360f)
.setDuration(500L)
.withEndAction(() -> v.setRotation(0f))
.start();
refreshUsers();
});
}
private void updateOrbitLayout() {
if (binding == null) return;
int size = binding.orbitContainer.getWidth();
if (size <= 0) return;
int avatarSize = binding.orbitUserTopAvatar.getWidth();
if (avatarSize <= 0 && binding.orbitUserTopAvatar.getLayoutParams() != null) {
avatarSize = binding.orbitUserTopAvatar.getLayoutParams().width;
}
if (avatarSize <= 0) return;
int outerRadius = size / 2;
orbitRadiusPx = outerRadius - (avatarSize / 2);
applyOrbitAngles();
}
private void applyOrbitAngles() {
if (binding == null) return;
if (orbitRadiusPx <= 0) return;
ConstraintSet set = new ConstraintSet();
set.clone(binding.orbitContainer);
set.constrainCircle(binding.orbitUserTop.getId(), binding.orbitCenter.getId(), orbitRadiusPx, normalizeAngle(ORBIT_BASE_ANGLES[0] + orbitAngleOffset));
set.constrainCircle(binding.orbitUserRight.getId(), binding.orbitCenter.getId(), orbitRadiusPx, normalizeAngle(ORBIT_BASE_ANGLES[1] + orbitAngleOffset));
set.constrainCircle(binding.orbitUserBottomRight.getId(), binding.orbitCenter.getId(), orbitRadiusPx, normalizeAngle(ORBIT_BASE_ANGLES[2] + orbitAngleOffset));
set.constrainCircle(binding.orbitUserBottomCenter.getId(), binding.orbitCenter.getId(), orbitRadiusPx, normalizeAngle(ORBIT_BASE_ANGLES[3] + orbitAngleOffset));
set.constrainCircle(binding.orbitUserBottomLeft.getId(), binding.orbitCenter.getId(), orbitRadiusPx, normalizeAngle(ORBIT_BASE_ANGLES[4] + orbitAngleOffset));
set.constrainCircle(binding.orbitUserLeft.getId(), binding.orbitCenter.getId(), orbitRadiusPx, normalizeAngle(ORBIT_BASE_ANGLES[5] + orbitAngleOffset));
set.applyTo(binding.orbitContainer);
}
private float normalizeAngle(float angle) {
float a = angle % 360f;
return a < 0f ? a + 360f : a;
}
private void startOrbitAnimationIfPossible() {
if (binding == null) return;
if (orbitRadiusPx <= 0) return;
if (orbitAnimator != null && orbitAnimator.isRunning()) return;
orbitAnimator = ValueAnimator.ofFloat(orbitAngleOffset, orbitAngleOffset + 360f);
orbitAnimator.setDuration(60000L); // 60s per revolution (slower)
orbitAnimator.setRepeatCount(ValueAnimator.INFINITE);
orbitAnimator.setRepeatMode(ValueAnimator.RESTART);
orbitAnimator.setInterpolator(new LinearInterpolator());
orbitAnimator.addUpdateListener(a -> {
orbitAngleOffset = (float) a.getAnimatedValue();
applyOrbitAngles();
});
orbitAnimator.start();
}
private View pickRandomOrbitUserView() {
if (binding == null) return null;
View[] users = new View[] {
binding.orbitUserTop,
binding.orbitUserRight,
binding.orbitUserBottomRight,
binding.orbitUserBottomCenter,
binding.orbitUserBottomLeft,
binding.orbitUserLeft
};
int idx = (int) (Math.random() * users.length);
return users[idx];
}
private void playBreathingPulse(View view) {
if (view == null) return;
// Don't fight with click animation: if user taps, click handler cancels and overrides.
view.animate().cancel();
float min = 1.0f;
float max = 1.10f + (float) (Math.random() * 0.05f); // 1.10 ~ 1.15
view.animate()
.scaleX(max)
.scaleY(max)
.setDuration(350L)
.setInterpolator(new LinearInterpolator())
.withEndAction(() -> view.animate()
.scaleX(min)
.scaleY(min)
.setDuration(650L)
.setInterpolator(new OvershootInterpolator(0.6f))
.start())
.start();
}
private void stopOrbitAnimation() {
if (orbitAnimator != null) {
orbitAnimator.cancel();
orbitAnimator = null;
}
}
private void startPulseLoop() {
uiHandler.removeCallbacks(pulseRunnable);
uiHandler.postDelayed(pulseRunnable, 600L);
}
private void stopPulseLoop() {
uiHandler.removeCallbacks(pulseRunnable);
}
private void refreshUsers() {
if (binding == null) return;
int[] avatars = new int[] {
R.drawable.wish_tree_checker_backup,
R.drawable.wish_tree_prev_no_bg,
R.drawable.wish_tree_trim_backup,
R.drawable.wish_tree_black,
R.drawable.wish_tree
};
String[] names = new String[] { "小树", "阿宁", "Lina", "暖暖", "小七", "小北", "Mika", "安安", "小鹿" };
String[] cities = new String[] { "杭州", "南宁", "深圳", "成都", "武汉", "西安", "上海", "北京", "重庆" };
userTop = bindUser("u_top", binding.orbitUserTopAvatar, binding.orbitUserTopName, binding.orbitUserTopLocation, avatars, names, cities);
userRight = bindUser("u_right", binding.orbitUserRightAvatar, binding.orbitUserRightName, binding.orbitUserRightLocation, avatars, names, cities);
userBottomRight = bindUser("u_bottom_right", binding.orbitUserBottomRightAvatar, binding.orbitUserBottomRightName, binding.orbitUserBottomRightLocation, avatars, names, cities);
userBottomCenter = bindUser("u_bottom_center", binding.orbitUserBottomCenterAvatar, binding.orbitUserBottomCenterName, binding.orbitUserBottomCenterLocation, avatars, names, cities);
userBottomLeft = bindUser("u_bottom_left", binding.orbitUserBottomLeftAvatar, binding.orbitUserBottomLeftName, binding.orbitUserBottomLeftLocation, avatars, names, cities);
userLeft = bindUser("u_left", binding.orbitUserLeftAvatar, binding.orbitUserLeftName, binding.orbitUserLeftLocation, avatars, names, cities);
}
private OrbitUserData bindUser(String id,
android.widget.ImageView avatarView,
android.widget.TextView nameView,
android.widget.TextView locationView,
int[] avatars,
String[] names,
String[] cities) {
if (avatarView == null || nameView == null || locationView == null) {
return new OrbitUserData(id, "", "", "", R.drawable.wish_tree_checker_backup);
}
int a = avatars[(int) (Math.random() * avatars.length)];
String n = names[(int) (Math.random() * names.length)];
String c = cities[(int) (Math.random() * cities.length)];
String bio = "真诚交友 · " + c + " · 在线";
avatarView.setImageResource(a);
nameView.setText(n);
locationView.setText(c);
avatarView.setAlpha(0.6f);
avatarView.animate().alpha(1f).setDuration(250L).start();
return new OrbitUserData(id, n, c, bio, a);
}
private void setupOrbitUserInteractions() {
if (binding == null) return;
binding.orbitUserTop.setOnClickListener(v -> onOrbitUserClick(v, userTop));
binding.orbitUserRight.setOnClickListener(v -> onOrbitUserClick(v, userRight));
binding.orbitUserBottomRight.setOnClickListener(v -> onOrbitUserClick(v, userBottomRight));
binding.orbitUserBottomCenter.setOnClickListener(v -> onOrbitUserClick(v, userBottomCenter));
binding.orbitUserBottomLeft.setOnClickListener(v -> onOrbitUserClick(v, userBottomLeft));
binding.orbitUserLeft.setOnClickListener(v -> onOrbitUserClick(v, userLeft));
}
private void onOrbitUserClick(View view, OrbitUserData user) {
if (view == null || user == null) return;
playAvatarClickEffect(view);
view.postDelayed(() -> UserProfileReadOnlyActivity.start(
this,
user.id,
user.name,
user.location,
user.bio,
user.avatarRes
), 120L);
}
private void playAvatarClickEffect(View view) {
if (view == null) return;
view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
view.animate().cancel();
float target = 1.08f;
long up = 120L;
long down = 320L;
view.animate()
.scaleX(target)
.scaleY(target)
.setDuration(up)
.withEndAction(() -> view.animate()
.scaleX(1f)
.scaleY(1f)
.setDuration(down)
.setInterpolator(new OvershootInterpolator(1.1f))
.start())
.start();
}
@Override
protected void onResume() {
super.onResume();
if (binding != null) {
binding.bottomNavInclude.bottomNavigation.setSelectedItemId(R.id.nav_friends);
}
// ensure radius computed before starting
if (binding != null) {
binding.orbitContainer.post(() -> {
updateOrbitLayout();
startOrbitAnimationIfPossible();
startPulseLoop();
});
}
}
@Override
protected void onPause() {
super.onPause();
stopOrbitAnimation();
stopPulseLoop();
}
}

View File

@ -202,7 +202,7 @@ public class MainActivity extends AppCompatActivity {
String avatarUri = getSharedPreferences("profile_prefs", MODE_PRIVATE)
.getString("profile_avatar_uri", null);
if (!TextUtils.isEmpty(avatarUri)) {
Glide.with(this).load(avatarUri).into(binding.avatarButton);
Glide.with(this).load(avatarUri).circleCrop().into(binding.avatarButton);
return;
}

View File

@ -33,6 +33,8 @@ public class ProfileActivity extends AppCompatActivity {
private static final String KEY_GENDER = "profile_gender";
private static final String KEY_LOCATION = "profile_location";
private static final String BIO_HINT_TEXT = "填写个人签名更容易获得关注,点击此处添加";
public static void start(Context context) {
Intent intent = new Intent(context, ProfileActivity.class);
context.startActivity(intent);
@ -82,14 +84,17 @@ public class ProfileActivity extends AppCompatActivity {
if (!TextUtils.isEmpty(n)) binding.name.setText(n);
String bio = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_BIO, null);
if (!TextUtils.isEmpty(bio)) {
if (!TextUtils.isEmpty(bio) && !BIO_HINT_TEXT.equals(bio)) {
binding.bioText.setText(bio);
binding.bioText.setTextColor(0xFF111111);
} else {
binding.bioText.setText(BIO_HINT_TEXT);
binding.bioText.setTextColor(0xFF999999);
}
String avatarUri = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_AVATAR_URI, null);
if (!TextUtils.isEmpty(avatarUri)) {
Glide.with(this).load(avatarUri).into(binding.avatar);
Glide.with(this).load(avatarUri).circleCrop().into(binding.avatar);
} else {
int avatarRes = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getInt(KEY_AVATAR_RES, 0);
if (avatarRes != 0) {
@ -106,17 +111,21 @@ public class ProfileActivity extends AppCompatActivity {
getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().putString(KEY_NAME, text).apply();
}));
binding.bioText.setOnClickListener(v -> showEditDialog("编辑签名", binding.bioText.getText() != null ? binding.bioText.getText().toString() : "", text -> {
if (TextUtils.isEmpty(text)) {
binding.bioText.setText("填写个人签名更容易获得关注,点击此处添加");
binding.bioText.setTextColor(0xFF999999);
getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().remove(KEY_BIO).apply();
} else {
binding.bioText.setText(text);
binding.bioText.setTextColor(0xFF111111);
getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().putString(KEY_BIO, text).apply();
}
}));
binding.bioText.setOnClickListener(v -> {
String current = binding.bioText.getText() != null ? binding.bioText.getText().toString() : "";
String initial = BIO_HINT_TEXT.equals(current) ? "" : current;
showEditDialog("编辑签名", initial, text -> {
if (TextUtils.isEmpty(text) || BIO_HINT_TEXT.equals(text)) {
binding.bioText.setText(BIO_HINT_TEXT);
binding.bioText.setTextColor(0xFF999999);
getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().remove(KEY_BIO).apply();
} else {
binding.bioText.setText(text);
binding.bioText.setTextColor(0xFF111111);
getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().putString(KEY_BIO, text).apply();
}
});
});
}
@ -194,6 +203,11 @@ public class ProfileActivity extends AppCompatActivity {
EditText editText = new EditText(this);
editText.setText(initialValue != null ? initialValue : "");
editText.setSelection(editText.getText() != null ? editText.getText().length() : 0);
editText.setTextColor(0xFF111111);
editText.setHintTextColor(0xFF999999);
if ("编辑签名".equals(title)) {
editText.setHint(BIO_HINT_TEXT);
}
int pad = (int) (16 * getResources().getDisplayMetrics().density);
editText.setPadding(pad, pad, pad, pad);

View File

@ -16,6 +16,7 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import com.bumptech.glide.Glide;
import com.example.livestreaming.databinding.ActivityTabPlaceholderBinding;
import com.example.livestreaming.net.Room;
@ -342,6 +343,32 @@ public class TabPlaceholderActivity extends AppCompatActivity {
binding.nearbyRecyclerView.setVisibility(View.GONE);
ensureMore();
updateMoreHeader();
}
private void updateMoreHeader() {
try {
String prefs = "profile_prefs";
String avatarUri = getSharedPreferences(prefs, MODE_PRIVATE).getString("profile_avatar_uri", null);
int avatarRes = getSharedPreferences(prefs, MODE_PRIVATE).getInt("profile_avatar_res", 0);
String name = getSharedPreferences(prefs, MODE_PRIVATE).getString("profile_name", "我的账号");
binding.moreName.setText(!TextUtils.isEmpty(name) ? name : "我的账号");
// keep the existing ID line format if any
if (binding.moreId.getText() == null || TextUtils.isEmpty(binding.moreId.getText().toString())) {
binding.moreId.setText("ID: 24187196");
}
if (!TextUtils.isEmpty(avatarUri)) {
Glide.with(this).load(avatarUri).circleCrop().into(binding.moreAvatar);
} else if (avatarRes != 0) {
binding.moreAvatar.setImageResource(avatarRes);
} else {
binding.moreAvatar.setImageResource(R.drawable.ic_account_circle_24);
}
} catch (Exception ignored) {
}
}
private void ensureMore() {
@ -387,7 +414,7 @@ public class TabPlaceholderActivity extends AppCompatActivity {
binding.moreRecyclerView.setLayoutManager(new LinearLayoutManager(this));
binding.moreRecyclerView.setAdapter(moreAdapter);
binding.moreEdit.setOnClickListener(v -> EditProfileActivity.start(this));
binding.moreEdit.setVisibility(View.GONE);
List<MoreItem> items = new ArrayList<>();
items.add(MoreItem.section("账号"));

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
<solid android:color="#00000000" />
<stroke android:width="4dp" android:color="#FFFFFFFF" />
<stroke android:width="0dp" android:color="#FFFFFFFF" />
</shape>

View File

@ -119,7 +119,8 @@
android:layout_width="64dp"
android:layout_height="64dp"
android:background="@drawable/bg_avatar_circle"
android:padding="10dp"
android:clipToOutline="true"
android:scaleType="centerCrop"
android:src="@drawable/ic_person_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
@ -158,6 +159,8 @@
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:hint="个人签名"
app:placeholderText="填写个人签名更容易获得关注,点击此处添加"
app:placeholderTextColor="#999999"
app:boxBackgroundMode="filled"
app:boxBackgroundColor="@android:color/white"
app:boxCornerRadiusTopStart="14dp"

View File

@ -78,89 +78,385 @@
</androidx.constraintlayout.widget.ConstraintLayout>
<FrameLayout
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/orbitContainer"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="18dp"
android:layout_marginBottom="12dp"
android:clipChildren="false"
android:clipToPadding="false"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/topCard"
app:layout_constraintBottom_toTopOf="@id/quickActions">
<View
android:layout_width="360dp"
android:layout_height="360dp"
android:layout_gravity="center"
android:background="@drawable/bg_orbit_ring" />
android:id="@+id/orbitRing"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/bg_orbit_ring"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/orbitCenter"
android:layout_width="1dp"
android:layout_height="1dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/centerButton"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_gravity="center"
android:background="@android:color/transparent"
android:clipToOutline="true"
android:elevation="10dp"
android:padding="0dp"
android:scaleType="fitCenter"
android:src="@drawable/ic_globe_clean_filled" />
android:src="@drawable/ic_globe_clean_filled"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_gravity="top|center_horizontal"
android:layout_marginTop="26dp"
android:background="@drawable/bg_avatar_ring"
android:src="@drawable/ic_account_circle_24" />
<LinearLayout
android:id="@+id/orbitUserTop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:clickable="true"
android:focusable="true"
android:gravity="center_horizontal"
android:orientation="vertical"
app:layout_constraintCircle="@id/orbitCenter"
app:layout_constraintCircleAngle="270"
app:layout_constraintCircleRadius="0dp">
<ImageView
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_gravity="center_vertical|start"
android:layout_marginStart="20dp"
android:background="@drawable/bg_avatar_ring"
android:src="@drawable/ic_account_circle_24" />
<FrameLayout
android:layout_width="72dp"
android:layout_height="72dp"
android:background="@drawable/bg_avatar_ring_pink"
android:padding="3dp">
<ImageView
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_gravity="center_vertical|end"
android:layout_marginEnd="20dp"
android:background="@drawable/bg_avatar_ring"
android:src="@drawable/ic_account_circle_24" />
<ImageView
android:id="@+id/orbitUserTopAvatar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_avatar_circle_transparent"
android:clipToOutline="true"
android:contentDescription="avatar"
android:scaleType="centerCrop"
android:src="@drawable/wish_tree_checker_backup" />
<ImageView
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_gravity="bottom|start"
android:layout_marginStart="72dp"
android:layout_marginBottom="26dp"
android:background="@drawable/bg_avatar_ring"
android:src="@drawable/ic_account_circle_24" />
</FrameLayout>
<ImageView
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_gravity="bottom|end"
android:layout_marginEnd="72dp"
android:layout_marginBottom="26dp"
android:background="@drawable/bg_avatar_ring"
android:src="@drawable/ic_account_circle_24" />
<TextView
android:id="@+id/orbitUserTopName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:maxLines="1"
android:text="小树"
android:textColor="#FFFFFF"
android:textSize="12sp"
android:textStyle="bold" />
<TextView
android:id="@+id/orbitUserTopLocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="杭州"
android:textColor="#CCFFFFFF"
android:textSize="10sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/orbitUserLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:clickable="true"
android:focusable="true"
android:gravity="center_horizontal"
android:orientation="vertical"
app:layout_constraintCircle="@id/orbitCenter"
app:layout_constraintCircleAngle="210"
app:layout_constraintCircleRadius="0dp">
<FrameLayout
android:layout_width="72dp"
android:layout_height="72dp"
android:background="@drawable/bg_avatar_ring_pink"
android:padding="3dp">
<ImageView
android:id="@+id/orbitUserLeftAvatar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_avatar_circle_transparent"
android:clipToOutline="true"
android:contentDescription="avatar"
android:scaleType="centerCrop"
android:src="@drawable/wish_tree_checker_backup" />
</FrameLayout>
<TextView
android:id="@+id/orbitUserLeftName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:maxLines="1"
android:text="阿宁"
android:textColor="#FFFFFF"
android:textSize="12sp"
android:textStyle="bold" />
<TextView
android:id="@+id/orbitUserLeftLocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="南宁"
android:textColor="#CCFFFFFF"
android:textSize="10sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/orbitUserRight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:clickable="true"
android:focusable="true"
android:gravity="center_horizontal"
android:orientation="vertical"
app:layout_constraintCircle="@id/orbitCenter"
app:layout_constraintCircleAngle="330"
app:layout_constraintCircleRadius="0dp">
<FrameLayout
android:layout_width="72dp"
android:layout_height="72dp"
android:background="@drawable/bg_avatar_ring_pink"
android:padding="3dp">
<ImageView
android:id="@+id/orbitUserRightAvatar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_avatar_circle_transparent"
android:clipToOutline="true"
android:contentDescription="avatar"
android:scaleType="centerCrop"
android:src="@drawable/wish_tree_checker_backup" />
</FrameLayout>
<TextView
android:id="@+id/orbitUserRightName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:maxLines="1"
android:text="Lina"
android:textColor="#FFFFFF"
android:textSize="12sp"
android:textStyle="bold" />
<TextView
android:id="@+id/orbitUserRightLocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="深圳"
android:textColor="#CCFFFFFF"
android:textSize="10sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/orbitUserBottomLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:clickable="true"
android:focusable="true"
android:gravity="center_horizontal"
android:orientation="vertical"
app:layout_constraintCircle="@id/orbitCenter"
app:layout_constraintCircleAngle="150"
app:layout_constraintCircleRadius="0dp">
<FrameLayout
android:layout_width="72dp"
android:layout_height="72dp"
android:background="@drawable/bg_avatar_ring_pink"
android:padding="3dp">
<ImageView
android:id="@+id/orbitUserBottomLeftAvatar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_avatar_circle_transparent"
android:clipToOutline="true"
android:contentDescription="avatar"
android:scaleType="centerCrop"
android:src="@drawable/wish_tree_checker_backup" />
</FrameLayout>
<TextView
android:id="@+id/orbitUserBottomLeftName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:maxLines="1"
android:text="暖暖"
android:textColor="#FFFFFF"
android:textSize="12sp"
android:textStyle="bold" />
<TextView
android:id="@+id/orbitUserBottomLeftLocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="成都"
android:textColor="#CCFFFFFF"
android:textSize="10sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/orbitUserBottomRight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:clickable="true"
android:focusable="true"
android:gravity="center_horizontal"
android:orientation="vertical"
app:layout_constraintCircle="@id/orbitCenter"
app:layout_constraintCircleAngle="30"
app:layout_constraintCircleRadius="0dp">
<FrameLayout
android:layout_width="72dp"
android:layout_height="72dp"
android:background="@drawable/bg_avatar_ring_pink"
android:padding="3dp">
<ImageView
android:id="@+id/orbitUserBottomRightAvatar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_avatar_circle_transparent"
android:clipToOutline="true"
android:contentDescription="avatar"
android:scaleType="centerCrop"
android:src="@drawable/wish_tree_checker_backup" />
</FrameLayout>
<TextView
android:id="@+id/orbitUserBottomRightName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:maxLines="1"
android:text="小七"
android:textColor="#FFFFFF"
android:textSize="12sp"
android:textStyle="bold" />
<TextView
android:id="@+id/orbitUserBottomRightLocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="武汉"
android:textColor="#CCFFFFFF"
android:textSize="10sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/orbitUserBottomCenter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:clickable="true"
android:focusable="true"
android:gravity="center_horizontal"
android:orientation="vertical"
app:layout_constraintCircle="@id/orbitCenter"
app:layout_constraintCircleAngle="90"
app:layout_constraintCircleRadius="0dp">
<FrameLayout
android:layout_width="72dp"
android:layout_height="72dp"
android:background="@drawable/bg_avatar_ring_pink"
android:padding="3dp">
<ImageView
android:id="@+id/orbitUserBottomCenterAvatar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_avatar_circle_transparent"
android:clipToOutline="true"
android:contentDescription="avatar"
android:scaleType="centerCrop"
android:src="@drawable/wish_tree_checker_backup" />
</FrameLayout>
<TextView
android:id="@+id/orbitUserBottomCenterName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:maxLines="1"
android:text="小北"
android:textColor="#FFFFFF"
android:textSize="12sp"
android:textStyle="bold" />
<TextView
android:id="@+id/orbitUserBottomCenterLocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="西安"
android:textColor="#CCFFFFFF"
android:textSize="10sp" />
</LinearLayout>
<ImageView
android:id="@+id/floatingMenu"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_gravity="bottom|end"
android:layout_marginEnd="18dp"
android:layout_marginBottom="18dp"
android:background="@drawable/bg_fishpond_fab_circle"
android:padding="10dp"
android:src="@drawable/ic_grid_24" />
android:src="@drawable/ic_grid_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.card.MaterialCardView
android:id="@+id/quickActions"

View File

@ -72,7 +72,10 @@
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_marginEnd="16dp"
android:background="@drawable/bg_avatar_circle"
android:clipToOutline="true"
android:contentDescription="avatar"
android:scaleType="centerCrop"
android:src="@drawable/ic_account_circle_24"
app:layout_constraintBottom_toBottomOf="@id/topTabs"
app:layout_constraintEnd_toEndOf="parent"

View File

@ -41,7 +41,8 @@
android:layout_width="84dp"
android:layout_height="84dp"
android:background="@drawable/bg_avatar_circle"
android:padding="10dp"
android:clipToOutline="true"
android:scaleType="centerCrop"
android:src="@drawable/ic_account_circle_24"
app:layout_constraintBottom_toBottomOf="@id/avatarRing"
app:layout_constraintEnd_toEndOf="@id/avatarRing"

View File

@ -487,8 +487,9 @@
android:id="@+id/moreAvatar"
android:layout_width="44dp"
android:layout_height="44dp"
android:background="@drawable/bg_avatar_circle"
android:padding="8dp"
android:background="@drawable/bg_avatar_circle_transparent"
android:clipToOutline="true"
android:scaleType="centerCrop"
android:src="@drawable/ic_account_circle_24"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@ -532,6 +533,7 @@
android:text="编辑"
android:textColor="#111111"
android:textSize="12sp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/moreAvatar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/moreAvatar" />