Compare commits

..

5 Commits

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="NullableNotNullManager">
@ -182,6 +183,13 @@
<component name="ProjectType">
<option name="id" value="Android" />
</component>
<component name="VisualizationToolProject">
<option name="state">
<ProjectState>
<option name="scale" value="0.24901855468749995" />
</ProjectState>
</option>
</component>
<component name="masterDetails">
<states>
<state key="ProjectJDKs.UI">

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/LLRiseTabBarDemo.iml" filepath="$PROJECT_DIR$/.idea/LLRiseTabBarDemo.iml" />
</modules>
</component>
</project>

@ -1,28 +1,60 @@
apply plugin: 'com.android.application'
// app/build.gradle
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android' // Kotlin
}
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
namespace "com.startsmake.llrisetabbardemo"
compileSdk 33
defaultConfig {
applicationId "com.startsmake.llrisetabbardemo"
minSdkVersion 14
targetSdkVersion 23
minSdk 21
targetSdk 33
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
namespace "com.startsmake.llrisetabbardemo"
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
testImplementation 'junit:junit:4.12'
implementation 'com.android.support:appcompat-v7:23.1.0'
testImplementation 'junit:junit:4.13.2'
// AndroidX
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.9.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.8.20"
//
implementation project(':mainnavigatetabbar')
}
//
configurations {
all {
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk7'
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8'
}
}
}

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.startsmake.llrisetabbardemo">
<application
android:allowBackup="true"
@ -7,13 +8,34 @@
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".activity.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<!-- 登录页面作为启动页 -->
<activity
android:name=".activity.LoginActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 主页面 -->
<activity
android:name=".activity.MainActivity"
android:exported="false" />
<!-- 注册页面 -->
<activity
android:name=".activity.RegisterActivity"
android:exported="false" />
<!-- 忘记密码页面 -->
<activity
android:name=".activity.ForgotPasswordActivity"
android:exported="false" />
<activity
android:name=".activity.ChatActivity"
android:exported="false" />
</application>
</manifest>
</manifest>

@ -0,0 +1,142 @@
package com.startsmake.llrisetabbardemo.activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.startsmake.llrisetabbardemo.R;
import com.startsmake.llrisetabbardemo.adapter.ChatMessageAdapter;
import com.startsmake.llrisetabbardemo.model.ChatMessage;
import java.util.ArrayList;
import java.util.List;
public class ChatActivity extends AppCompatActivity {
private TextView tvTitle;
private ImageView ivBack;
private RecyclerView rvChatMessages;
private EditText etMessage;
private ImageButton btnSend;
private ChatMessageAdapter chatAdapter;
private List<ChatMessage> messageList;
private String chatTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
// 获取传递过来的聊天标题
chatTitle = getIntent().getStringExtra("chat_title");
if (chatTitle == null) {
chatTitle = "聊天";
}
initView();
initData();
setupClickListeners();
}
private void initView() {
tvTitle = findViewById(R.id.tvTitle);
ivBack = findViewById(R.id.ivBack);
rvChatMessages = findViewById(R.id.rvChatMessages);
etMessage = findViewById(R.id.etMessage);
btnSend = findViewById(R.id.btnSend);
tvTitle.setText(chatTitle);
}
private void initData() {
messageList = new ArrayList<>();
// 添加一些初始消息
if ("通知消息".equals(chatTitle)) {
messageList.add(new ChatMessage("系统", "红包到账提醒", "10:30", false));
messageList.add(new ChatMessage("我", "收到了,谢谢!", "10:31", true));
} else if ("刑事组之虎".equals(chatTitle)) {
messageList.add(new ChatMessage("刑事组之虎", "快给ta一个评价吧", "04-19 14:20", false));
messageList.add(new ChatMessage("我", "已经评价了,商品很不错!", "04-19 14:25", true));
} else {
messageList.add(new ChatMessage(chatTitle, "你好!", "刚刚", false));
}
chatAdapter = new ChatMessageAdapter(this, messageList);
rvChatMessages.setLayoutManager(new LinearLayoutManager(this));
rvChatMessages.setAdapter(chatAdapter);
// 滚动到底部
rvChatMessages.scrollToPosition(messageList.size() - 1);
}
private void setupClickListeners() {
// 返回按钮
ivBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
// 发送按钮
btnSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sendMessage();
}
});
}
private void sendMessage() {
String message = etMessage.getText().toString().trim();
if (!TextUtils.isEmpty(message)) {
// 添加新消息到列表
ChatMessage newMessage = new ChatMessage("我", message, "刚刚", true);
messageList.add(newMessage);
chatAdapter.notifyItemInserted(messageList.size() - 1);
// 清空输入框
etMessage.setText("");
// 滚动到底部
rvChatMessages.scrollToPosition(messageList.size() - 1);
// 模拟对方回复(可选)
simulateReply(message);
}
}
private void simulateReply(String userMessage) {
// 延迟模拟回复
rvChatMessages.postDelayed(new Runnable() {
@Override
public void run() {
String reply = generateReply(userMessage);
ChatMessage replyMessage = new ChatMessage(chatTitle, reply, "刚刚", false);
messageList.add(replyMessage);
chatAdapter.notifyItemInserted(messageList.size() - 1);
rvChatMessages.scrollToPosition(messageList.size() - 1);
}
}, 1000);
}
private String generateReply(String userMessage) {
// 简单的回复逻辑
if (userMessage.contains("你好") || userMessage.contains("在吗")) {
return "在的,有什么可以帮您?";
} else if (userMessage.contains("价格") || userMessage.contains("多少钱")) {
return "这个商品价格是xxx元";
} else if (userMessage.contains("谢谢")) {
return "不客气!";
} else {
return "收到您的消息了!";
}
}
}

@ -0,0 +1,151 @@
package com.startsmake.llrisetabbardemo.activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.textfield.TextInputEditText;
import com.startsmake.llrisetabbardemo.R;
public class ForgotPasswordActivity extends AppCompatActivity {
private TextInputEditText etPhone, etVerificationCode, etNewPassword;
private Button btnSendCode, btnResetPassword;
private ImageButton btnBack;
private TextView tvLogin;
private CountDownTimer countDownTimer;
private boolean isCounting = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_forgot_password);
initViews();
setupClickListeners();
}
private void initViews() {
etPhone = findViewById(R.id.et_phone);
etVerificationCode = findViewById(R.id.et_verification_code);
etNewPassword = findViewById(R.id.et_new_password);
btnSendCode = findViewById(R.id.btn_send_code);
btnResetPassword = findViewById(R.id.btn_reset_password);
btnBack = findViewById(R.id.btn_back);
tvLogin = findViewById(R.id.tv_login);
}
private void setupClickListeners() {
// 返回按钮
btnBack.setOnClickListener(v -> finish());
// 发送验证码
btnSendCode.setOnClickListener(v -> sendVerificationCode());
// 重置密码按钮
btnResetPassword.setOnClickListener(v -> attemptResetPassword());
// 返回登录
tvLogin.setOnClickListener(v -> {
Intent intent = new Intent(ForgotPasswordActivity.this, LoginActivity.class);
startActivity(intent);
finish();
});
}
private void sendVerificationCode() {
String phone = etPhone.getText().toString().trim();
if (phone.isEmpty()) {
etPhone.setError("请输入手机号");
return;
}
if (phone.length() != 11) {
etPhone.setError("手机号格式不正确");
return;
}
if (!isCounting) {
startCountDown();
Toast.makeText(this, "验证码已发送", Toast.LENGTH_SHORT).show();
// 这里应该调用后端API发送验证码
}
}
private void startCountDown() {
isCounting = true;
btnSendCode.setEnabled(false);
countDownTimer = new CountDownTimer(60000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
btnSendCode.setText(millisUntilFinished / 1000 + "秒后重发");
}
@Override
public void onFinish() {
isCounting = false;
btnSendCode.setEnabled(true);
btnSendCode.setText("发送验证码");
}
}.start();
}
private void attemptResetPassword() {
String phone = etPhone.getText().toString().trim();
String code = etVerificationCode.getText().toString().trim();
String newPassword = etNewPassword.getText().toString().trim();
if (phone.isEmpty()) {
etPhone.setError("请输入手机号");
return;
}
if (code.isEmpty()) {
etVerificationCode.setError("请输入验证码");
return;
}
if (newPassword.isEmpty()) {
etNewPassword.setError("请输入新密码");
return;
}
if (phone.length() != 11) {
etPhone.setError("手机号格式不正确");
return;
}
if (newPassword.length() < 6) {
etNewPassword.setError("密码至少6位");
return;
}
// 模拟重置密码成功
performResetPassword();
}
private void performResetPassword() {
Toast.makeText(this, "密码重置成功!", Toast.LENGTH_SHORT).show();
// 重置成功后跳转到登录页面
Intent intent = new Intent(ForgotPasswordActivity.this, LoginActivity.class);
startActivity(intent);
finish();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (countDownTimer != null) {
countDownTimer.cancel();
}
}
}

@ -0,0 +1,96 @@
package com.startsmake.llrisetabbardemo.activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.textfield.TextInputEditText;
import com.startsmake.llrisetabbardemo.R;
public class LoginActivity extends AppCompatActivity {
private TextInputEditText etPhone, etPassword;
private Button btnLogin, btnSkipLogin;
private TextView tvForgotPassword, tvRegister;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
initViews();
setupClickListeners();
}
private void initViews() {
etPhone = findViewById(R.id.et_phone);
etPassword = findViewById(R.id.et_password);
btnLogin = findViewById(R.id.btn_login);
btnSkipLogin = findViewById(R.id.btn_skip_login);
tvForgotPassword = findViewById(R.id.tv_forgot_password);
tvRegister = findViewById(R.id.tv_register);
}
private void setupClickListeners() {
// 登录按钮
btnLogin.setOnClickListener(v -> attemptLogin());
// 跳过登录按钮
btnSkipLogin.setOnClickListener(v -> skipToMain());
// 忘记密码
tvForgotPassword.setOnClickListener(v -> {
Intent intent = new Intent(LoginActivity.this, ForgotPasswordActivity.class);
startActivity(intent);
});
// 注册
tvRegister.setOnClickListener(v -> {
Intent intent = new Intent(LoginActivity.this, RegisterActivity.class);
startActivity(intent);
});
}
private void attemptLogin() {
String phone = etPhone.getText().toString().trim();
String password = etPassword.getText().toString().trim();
if (phone.isEmpty()) {
etPhone.setError("请输入手机号");
return;
}
if (password.isEmpty()) {
etPassword.setError("请输入密码");
return;
}
if (phone.length() != 11) {
etPhone.setError("手机号格式不正确");
return;
}
// 模拟登录成功(因为没有后端)
performLogin();
}
private void performLogin() {
Toast.makeText(this, "登录成功!", Toast.LENGTH_SHORT).show();
navigateToMain();
}
private void skipToMain() {
Toast.makeText(this, "跳过登录,进入主界面", Toast.LENGTH_SHORT).show();
navigateToMain();
}
private void navigateToMain() {
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
}

@ -1,10 +1,12 @@
package com.startsmake.llrisetabbardemo.activity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;
// 改为 AndroidX
import androidx.appcompat.app.AppCompatActivity;
import com.startsmake.llrisetabbardemo.R;
import com.startsmake.llrisetabbardemo.fragment.CityFragment;
import com.startsmake.llrisetabbardemo.fragment.HomeFragment;
@ -20,7 +22,6 @@ public class MainActivity extends AppCompatActivity {
private static final String TAG_PAGE_MESSAGE = "消息";
private static final String TAG_PAGE_PERSON = "我的";
private MainNavigateTabBar mNavigateTabBar;
@Override
@ -39,15 +40,13 @@ public class MainActivity extends AppCompatActivity {
mNavigateTabBar.addTab(PersonFragment.class, new MainNavigateTabBar.TabParam(R.mipmap.comui_tab_person, R.mipmap.comui_tab_person_selected, TAG_PAGE_PERSON));
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mNavigateTabBar.onSaveInstanceState(outState);
}
public void onClickPublish(View v) {
Toast.makeText(this, "发布", Toast.LENGTH_LONG).show();
}
}
}

@ -0,0 +1,151 @@
package com.startsmake.llrisetabbardemo.activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.textfield.TextInputEditText;
import com.startsmake.llrisetabbardemo.R;
public class RegisterActivity extends AppCompatActivity {
private TextInputEditText etPhone, etVerificationCode, etPassword;
private Button btnSendCode, btnRegister;
private ImageButton btnBack;
private TextView tvLogin;
private CountDownTimer countDownTimer;
private boolean isCounting = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
initViews();
setupClickListeners();
}
private void initViews() {
etPhone = findViewById(R.id.et_phone);
etVerificationCode = findViewById(R.id.et_verification_code);
etPassword = findViewById(R.id.et_password);
btnSendCode = findViewById(R.id.btn_send_code);
btnRegister = findViewById(R.id.btn_register);
btnBack = findViewById(R.id.btn_back);
tvLogin = findViewById(R.id.tv_login);
}
private void setupClickListeners() {
// 返回按钮
btnBack.setOnClickListener(v -> finish());
// 发送验证码
btnSendCode.setOnClickListener(v -> sendVerificationCode());
// 注册按钮
btnRegister.setOnClickListener(v -> attemptRegister());
// 立即登录
tvLogin.setOnClickListener(v -> {
Intent intent = new Intent(RegisterActivity.this, LoginActivity.class);
startActivity(intent);
finish();
});
}
private void sendVerificationCode() {
String phone = etPhone.getText().toString().trim();
if (phone.isEmpty()) {
etPhone.setError("请输入手机号");
return;
}
if (phone.length() != 11) {
etPhone.setError("手机号格式不正确");
return;
}
if (!isCounting) {
startCountDown();
Toast.makeText(this, "验证码已发送", Toast.LENGTH_SHORT).show();
// 这里应该调用后端API发送验证码
}
}
private void startCountDown() {
isCounting = true;
btnSendCode.setEnabled(false);
countDownTimer = new CountDownTimer(60000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
btnSendCode.setText(millisUntilFinished / 1000 + "秒后重发");
}
@Override
public void onFinish() {
isCounting = false;
btnSendCode.setEnabled(true);
btnSendCode.setText("发送验证码");
}
}.start();
}
private void attemptRegister() {
String phone = etPhone.getText().toString().trim();
String code = etVerificationCode.getText().toString().trim();
String password = etPassword.getText().toString().trim();
if (phone.isEmpty()) {
etPhone.setError("请输入手机号");
return;
}
if (code.isEmpty()) {
etVerificationCode.setError("请输入验证码");
return;
}
if (password.isEmpty()) {
etPassword.setError("请输入密码");
return;
}
if (phone.length() != 11) {
etPhone.setError("手机号格式不正确");
return;
}
if (password.length() < 6) {
etPassword.setError("密码至少6位");
return;
}
// 模拟注册成功
performRegister();
}
private void performRegister() {
Toast.makeText(this, "注册成功!", Toast.LENGTH_SHORT).show();
// 注册成功后跳转到登录页面
Intent intent = new Intent(RegisterActivity.this, LoginActivity.class);
startActivity(intent);
finish();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (countDownTimer != null) {
countDownTimer.cancel();
}
}
}

@ -0,0 +1,74 @@
package com.startsmake.llrisetabbardemo.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.startsmake.llrisetabbardemo.R;
import com.startsmake.llrisetabbardemo.model.ChatMessage;
import java.util.List;
public class ChatMessageAdapter extends RecyclerView.Adapter<ChatMessageAdapter.ViewHolder> {
private Context context;
private List<ChatMessage> messageList;
public ChatMessageAdapter(Context context, List<ChatMessage> messageList) {
this.context = context;
this.messageList = messageList;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_chat_message, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
ChatMessage message = messageList.get(position);
if (message.isMe()) {
// 自己发送的消息 - 右侧显示
holder.layoutLeft.setVisibility(View.GONE);
holder.layoutRight.setVisibility(View.VISIBLE);
holder.tvRightMessage.setText(message.getContent());
holder.tvRightTime.setText(message.getTime());
} else {
// 对方发送的消息 - 左侧显示
holder.layoutRight.setVisibility(View.GONE);
holder.layoutLeft.setVisibility(View.VISIBLE);
holder.tvLeftMessage.setText(message.getContent());
holder.tvLeftTime.setText(message.getTime());
}
}
@Override
public int getItemCount() {
return messageList.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
LinearLayout layoutLeft;
LinearLayout layoutRight;
TextView tvLeftMessage;
TextView tvRightMessage;
TextView tvLeftTime;
TextView tvRightTime;
public ViewHolder(@NonNull View itemView) {
super(itemView);
layoutLeft = itemView.findViewById(R.id.layoutLeft);
layoutRight = itemView.findViewById(R.id.layoutRight);
tvLeftMessage = itemView.findViewById(R.id.tvLeftMessage);
tvRightMessage = itemView.findViewById(R.id.tvRightMessage);
tvLeftTime = itemView.findViewById(R.id.tvLeftTime);
tvRightTime = itemView.findViewById(R.id.tvRightTime);
}
}
}

@ -0,0 +1,102 @@
package com.startsmake.llrisetabbardemo.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.startsmake.llrisetabbardemo.R;
import com.startsmake.llrisetabbardemo.model.MessageItem;
import java.util.List;
public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.ViewHolder> {
private Context context;
private List<MessageItem> messageList;
private OnItemClickListener onItemClickListener;
public MessageAdapter(Context context, List<MessageItem> messageList) {
this.context = context;
this.messageList = messageList;
}
// 添加点击监听接口
public interface OnItemClickListener {
void onItemClick(MessageItem item);
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.onItemClickListener = listener;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_message, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
MessageItem item = messageList.get(position);
// 设置默认白色头像背景
holder.ivAvatar.setBackgroundResource(R.drawable.bg_avatar_placeholder);
holder.tvTitle.setText(item.getTitle());
holder.tvContent.setText(item.getContent());
holder.tvTime.setText(item.getTime());
// 未读消息数量
if (item.getUnreadCount() > 0) {
holder.tvUnreadCount.setVisibility(View.VISIBLE);
holder.tvUnreadCount.setText(String.valueOf(item.getUnreadCount()));
} else {
holder.tvUnreadCount.setVisibility(View.GONE);
}
// 官方标识
if (item.isOfficial()) {
holder.ivOfficial.setVisibility(View.VISIBLE);
} else {
holder.ivOfficial.setVisibility(View.GONE);
}
// 添加点击事件
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onItemClickListener != null) {
onItemClickListener.onItemClick(item);
}
}
});
}
@Override
public int getItemCount() {
return messageList.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
ImageView ivAvatar;
TextView tvTitle;
TextView tvContent;
TextView tvTime;
TextView tvUnreadCount;
ImageView ivOfficial;
public ViewHolder(@NonNull View itemView) {
super(itemView);
ivAvatar = itemView.findViewById(R.id.ivAvatar);
tvTitle = itemView.findViewById(R.id.tvTitle);
tvContent = itemView.findViewById(R.id.tvContent);
tvTime = itemView.findViewById(R.id.tvTime);
tvUnreadCount = itemView.findViewById(R.id.tvUnreadCount);
ivOfficial = itemView.findViewById(R.id.ivOfficial);
}
}
}

@ -1,12 +1,14 @@
package com.startsmake.llrisetabbardemo.fragment;
import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
// 改为 AndroidX
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.startsmake.llrisetabbardemo.R;
/**
@ -21,4 +23,4 @@ public class CityFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_city, container, false);
}
}
}

@ -1,12 +1,14 @@
package com.startsmake.llrisetabbardemo.fragment;
import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
// 改为 AndroidX
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.startsmake.llrisetabbardemo.R;
/**
@ -21,5 +23,4 @@ public class HomeFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_home, container, false);
}
}
}

@ -1,24 +1,65 @@
package com.startsmake.llrisetabbardemo.fragment;
import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.startsmake.llrisetabbardemo.R;
import com.startsmake.llrisetabbardemo.activity.ChatActivity;
import com.startsmake.llrisetabbardemo.adapter.MessageAdapter;
import com.startsmake.llrisetabbardemo.model.MessageItem;
import java.util.ArrayList;
import java.util.List;
/**
* User:Shine
* Date:2015-10-20
* Description:
*/
public class MessageFragment extends Fragment {
private RecyclerView rvMessageList;
private MessageAdapter messageAdapter;
private List<MessageItem> messageList;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_message, container, false);
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_message, container, false);
initView(view);
initData();
return view;
}
private void initView(View view) {
rvMessageList = view.findViewById(R.id.rvMessageList);
rvMessageList.setLayoutManager(new LinearLayoutManager(getContext()));
}
private void initData() {
messageList = new ArrayList<>();
// 添加消息数据 - 所有头像都使用白色背景
messageList.add(new MessageItem("通知消息", "红包到账提醒", "刚刚", 0, true));
messageList.add(new MessageItem("互动消息", "还没有新通知~", "", 0, false));
messageList.add(new MessageItem("闲鱼精选", "[347条] 关注的宝贝上新捡漏...", "6小时前", 347, false));
messageList.add(new MessageItem("刑事组之虎", "快给ta一个评价吧", "04-19", 0, false));
messageList.add(new MessageItem("卖家小助手", "开启急速转卖通道!", "05-25", 0, true));
messageList.add(new MessageItem("豫中玩具批…", "[我完成了评价]", "04-18", 0, false));
messageAdapter = new MessageAdapter(getContext(), messageList);
rvMessageList.setAdapter(messageAdapter);
// 添加点击监听
messageAdapter.setOnItemClickListener(new MessageAdapter.OnItemClickListener() {
@Override
public void onItemClick(MessageItem item) {
// 跳转到聊天页面
Intent intent = new Intent(getActivity(), ChatActivity.class);
intent.putExtra("chat_title", item.getTitle());
startActivity(intent);
}
});
}
}
}

@ -1,12 +1,14 @@
package com.startsmake.llrisetabbardemo.fragment;
import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
// 改为 AndroidX
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.startsmake.llrisetabbardemo.R;
/**
@ -21,4 +23,4 @@ public class PersonFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_person, container, false);
}
}
}

@ -0,0 +1,28 @@
package com.startsmake.llrisetabbardemo.model;
public class ChatMessage {
private String sender;
private String content;
private String time;
private boolean isMe;
public ChatMessage(String sender, String content, String time, boolean isMe) {
this.sender = sender;
this.content = content;
this.time = time;
this.isMe = isMe;
}
// Getter and Setter methods
public String getSender() { return sender; }
public void setSender(String sender) { this.sender = sender; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
public String getTime() { return time; }
public void setTime(String time) { this.time = time; }
public boolean isMe() { return isMe; }
public void setMe(boolean me) { isMe = me; }
}

@ -0,0 +1,33 @@
package com.startsmake.llrisetabbardemo.model;
public class MessageItem {
private String title;
private String content;
private String time;
private int unreadCount;
private boolean isOfficial;
public MessageItem(String title, String content, String time, int unreadCount, boolean isOfficial) {
this.title = title;
this.content = content;
this.time = time;
this.unreadCount = unreadCount;
this.isOfficial = isOfficial;
}
// Getter and Setter methods
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
public String getTime() { return time; }
public void setTime(String time) { this.time = time; }
public int getUnreadCount() { return unreadCount; }
public void setUnreadCount(int unreadCount) { this.unreadCount = unreadCount; }
public boolean isOfficial() { return isOfficial; }
public void setOfficial(boolean official) { isOfficial = official; }
}

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

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#20FFD700" />
<corners android:radius="8dp" />
</shape>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFD700" />
<corners android:radius="24dp" />
</shape>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#20FFD700" />
<corners android:radius="24dp" />
<stroke android:width="1dp" android:color="#FFD700" />
</shape>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#f5f5f5" />
<corners android:radius="24dp" />
<stroke
android:width="1dp"
android:color="#e0e0e0" />
</shape>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@android:color/white" />
<corners
android:topLeftRadius="0dp"
android:topRightRadius="16dp"
android:bottomLeftRadius="16dp"
android:bottomRightRadius="16dp" />
<stroke
android:width="1dp"
android:color="#e0e0e0" />
</shape>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#07C160" />
<corners
android:topLeftRadius="16dp"
android:topRightRadius="0dp"
android:bottomLeftRadius="16dp"
android:bottomRightRadius="16dp" />
</shape>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#f5f5f5" />
<corners android:radius="18dp" />
</shape>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FF5000" />
<corners android:radius="9dp" />
</shape>

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="#333333">
<path
android:fillColor="@android:color/white"
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
</vector>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="12dp"
android:height="12dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF5000"
android:pathData="M12,2L4,5v6.09c0,5.05 3.41,9.76 8,10.91c4.59,-1.15 8,-5.86 8,-10.91V5L12,2z"/>
</vector>

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#f5f5f5">
<!-- 标题栏 -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="@android:color/white"
android:elevation="2dp">
<ImageView
android:id="@+id/ivBack"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@android:drawable/ic_menu_close_clear_cancel"
android:layout_centerVertical="true"
android:layout_marginStart="16dp" />
<TextView
android:id="@+id/tvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="聊天"
android:textSize="18sp"
android:textStyle="bold"
android:layout_centerInParent="true" />
</RelativeLayout>
<!-- 聊天消息列表 -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvChatMessages"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<!-- 输入框区域 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:orientation="horizontal"
android:padding="8dp"
android:elevation="4dp">
<EditText
android:id="@+id/etMessage"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/bg_chat_input"
android:hint="输入消息..."
android:maxLines="3"
android:padding="12dp"
android:textSize="14sp" />
<ImageButton
android:id="@+id/btnSend"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?android:attr/selectableItemBackground"
android:src="@android:drawable/ic_menu_send"
android:layout_marginStart="8dp" />
</LinearLayout>
</LinearLayout>

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="32dp">
<!-- 返回按钮 -->
<ImageButton
android:id="@+id/btn_back"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:src="@drawable/ic_arrow_back"
android:tint="#333333" />
<!-- 标题 -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:layout_marginBottom="40dp"
android:text="忘记密码"
android:textColor="#333333"
android:textSize="24sp"
android:textStyle="bold" />
<!-- 手机号输入框 -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
app:boxCornerRadiusBottomEnd="12dp"
app:boxCornerRadiusBottomStart="12dp"
app:boxCornerRadiusTopEnd="12dp"
app:boxCornerRadiusTopStart="12dp"
app:boxStrokeColor="#FFD700"
app:hintTextColor="#999999">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="手机号"
android:inputType="phone"
android:maxLines="1"
android:padding="16dp"
android:textColor="#333333"
android:textSize="16sp" />
</com.google.android.material.textfield.TextInputLayout>
<!-- 验证码输入框 -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
app:boxCornerRadiusBottomEnd="12dp"
app:boxCornerRadiusBottomStart="12dp"
app:boxCornerRadiusTopEnd="12dp"
app:boxCornerRadiusTopStart="12dp"
app:boxStrokeColor="#FFD700"
app:hintTextColor="#999999">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_verification_code"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="验证码"
android:inputType="number"
android:maxLines="1"
android:padding="16dp"
android:textColor="#333333"
android:textSize="16sp" />
<Button
android:id="@+id/btn_send_code"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="8dp"
android:background="@drawable/bg_button_code"
android:text="发送验证码"
android:textColor="#FFD700"
android:textSize="12sp" />
</LinearLayout>
</com.google.android.material.textfield.TextInputLayout>
<!-- 新密码输入框 -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
app:boxCornerRadiusBottomEnd="12dp"
app:boxCornerRadiusBottomStart="12dp"
app:boxCornerRadiusTopEnd="12dp"
app:boxCornerRadiusTopStart="12dp"
app:boxStrokeColor="#FFD700"
app:hintTextColor="#999999">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_new_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="设置新密码"
android:inputType="textPassword"
android:maxLines="1"
android:padding="16dp"
android:textColor="#333333"
android:textSize="16sp" />
</com.google.android.material.textfield.TextInputLayout>
<!-- 重置密码按钮 -->
<Button
android:id="@+id/btn_reset_password"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@drawable/bg_button_primary"
android:text="重置密码"
android:textColor="#333333"
android:textSize="16sp"
android:textStyle="bold" />
<!-- 底部链接 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="想起密码?"
android:textColor="#666666"
android:textSize="14sp" />
<TextView
android:id="@+id/tv_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="返回登录"
android:textColor="#FFD700"
android:textSize="14sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</ScrollView>

@ -0,0 +1,145 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="32dp">
<!-- Logo -->
<ImageView
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="60dp"
android:layout_marginBottom="40dp"
android:src="@mipmap/ic_launcher"
android:tint="#FFD700" />
<!-- 标题 -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="40dp"
android:text="BudgetFindly"
android:textColor="#333333"
android:textSize="24sp"
android:textStyle="bold" />
<!-- 手机号输入框 -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
app:boxCornerRadiusBottomEnd="12dp"
app:boxCornerRadiusBottomStart="12dp"
app:boxCornerRadiusTopEnd="12dp"
app:boxCornerRadiusTopStart="12dp"
app:boxStrokeColor="#FFD700"
app:hintTextColor="#999999">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="手机号"
android:inputType="phone"
android:maxLines="1"
android:padding="16dp"
android:textColor="#333333"
android:textSize="16sp" />
</com.google.android.material.textfield.TextInputLayout>
<!-- 密码输入框 -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
app:boxCornerRadiusBottomEnd="12dp"
app:boxCornerRadiusBottomStart="12dp"
app:boxCornerRadiusTopEnd="12dp"
app:boxCornerRadiusTopStart="12dp"
app:boxStrokeColor="#FFD700"
app:hintTextColor="#999999">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="密码"
android:inputType="textPassword"
android:maxLines="1"
android:padding="16dp"
android:textColor="#333333"
android:textSize="16sp" />
</com.google.android.material.textfield.TextInputLayout>
<!-- 登录按钮 -->
<Button
android:id="@+id/btn_login"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@drawable/bg_button_primary"
android:text="登录"
android:textColor="#333333"
android:textSize="16sp"
android:textStyle="bold" />
<!-- 跳过登录按钮 -->
<Button
android:id="@+id/btn_skip_login"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="12dp"
android:background="@drawable/bg_button_secondary"
android:text="跳过登录"
android:textColor="#FFD700"
android:textSize="16sp" />
<!-- 底部链接 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_forgot_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="忘记密码?"
android:textColor="#FFD700"
android:textSize="14sp"
android:textStyle="bold" />
<View
android:layout_width="1dp"
android:layout_height="12dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:background="#DDDDDD" />
<TextView
android:id="@+id/tv_register"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="立即注册"
android:textColor="#FFD700"
android:textSize="14sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</ScrollView>

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="32dp">
<!-- 返回按钮 -->
<ImageButton
android:id="@+id/btn_back"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:src="@drawable/ic_arrow_back"
android:tint="#333333" />
<!-- 标题 -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:layout_marginBottom="40dp"
android:text="注册账号"
android:textColor="#333333"
android:textSize="24sp"
android:textStyle="bold" />
<!-- 手机号输入框 -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
app:boxCornerRadiusBottomEnd="12dp"
app:boxCornerRadiusBottomStart="12dp"
app:boxCornerRadiusTopEnd="12dp"
app:boxCornerRadiusTopStart="12dp"
app:boxStrokeColor="#FFD700"
app:hintTextColor="#999999">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="手机号"
android:inputType="phone"
android:maxLines="1"
android:padding="16dp"
android:textColor="#333333"
android:textSize="16sp" />
</com.google.android.material.textfield.TextInputLayout>
<!-- 验证码输入框 -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
app:boxCornerRadiusBottomEnd="12dp"
app:boxCornerRadiusBottomStart="12dp"
app:boxCornerRadiusTopEnd="12dp"
app:boxCornerRadiusTopStart="12dp"
app:boxStrokeColor="#FFD700"
app:hintTextColor="#999999">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_verification_code"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="验证码"
android:inputType="number"
android:maxLines="1"
android:padding="16dp"
android:textColor="#333333"
android:textSize="16sp" />
<Button
android:id="@+id/btn_send_code"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="8dp"
android:background="@drawable/bg_button_code"
android:text="发送验证码"
android:textColor="#FFD700"
android:textSize="12sp" />
</LinearLayout>
</com.google.android.material.textfield.TextInputLayout>
<!-- 密码输入框 -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
app:boxCornerRadiusBottomEnd="12dp"
app:boxCornerRadiusBottomStart="12dp"
app:boxCornerRadiusTopEnd="12dp"
app:boxCornerRadiusTopStart="12dp"
app:boxStrokeColor="#FFD700"
app:hintTextColor="#999999">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="设置密码"
android:inputType="textPassword"
android:maxLines="1"
android:padding="16dp"
android:textColor="#333333"
android:textSize="16sp" />
</com.google.android.material.textfield.TextInputLayout>
<!-- 注册按钮 -->
<Button
android:id="@+id/btn_register"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@drawable/bg_button_primary"
android:text="注册"
android:textColor="#333333"
android:textSize="16sp"
android:textStyle="bold" />
<!-- 底部链接 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="已有账号?"
android:textColor="#666666"
android:textSize="14sp" />
<TextView
android:id="@+id/tv_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="立即登录"
android:textColor="#FFD700"
android:textSize="14sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</ScrollView>

@ -1,14 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:orientation="vertical"
android:background="#f5f5f5">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="消息"/>
<!-- 标题栏 -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="@android:color/white"
android:elevation="2dp">
</FrameLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="消息"
android:textSize="18sp"
android:textStyle="bold"
android:layout_centerInParent="true" />
</RelativeLayout>
<!-- 搜索栏 -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@android:color/white"
android:paddingHorizontal="16dp"
android:layout_marginTop="8dp">
<EditText
android:id="@+id/etSearch"
android:layout_width="match_parent"
android:layout_height="36dp"
android:background="@drawable/bg_search_edittext"
android:hint="搜索聊天记录/联系人/服务号"
android:paddingStart="40dp"
android:paddingEnd="16dp"
android:singleLine="true"
android:textSize="14sp" />
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@android:drawable/ic_menu_search"
android:layout_centerVertical="true"
android:layout_marginStart="12dp" />
</RelativeLayout>
<!-- 消息列表 -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvMessageList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp" />
</LinearLayout>

@ -0,0 +1,118 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="8dp">
<!-- 对方消息(左侧) -->
<LinearLayout
android:id="@+id/layoutLeft"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:paddingHorizontal="16dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingEnd="48dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_chat_message_left"
android:orientation="vertical"
android:padding="12dp">
<TextView
android:id="@+id/tvLeftMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="对方消息"
android:textColor="@android:color/black"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/tvLeftTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="时间"
android:textColor="#999999"
android:textSize="10sp"
android:layout_marginTop="4dp"
android:layout_marginStart="12dp" />
</LinearLayout>
</LinearLayout>
<!-- 自己消息(右侧) -->
<LinearLayout
android:id="@+id/layoutRight"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:paddingHorizontal="16dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="end"
android:paddingStart="48dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_chat_message_right"
android:orientation="vertical"
android:padding="12dp">
<TextView
android:id="@+id/tvRightMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我的消息"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/tvRightTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="时间"
android:textColor="#999999"
android:textSize="10sp"
android:layout_marginTop="4dp"
android:layout_gravity="end"
android:layout_marginEnd="12dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="72dp"
android:background="@android:color/white"
android:padding="12dp">
<!-- 白色头像占位 -->
<ImageView
android:id="@+id/ivAvatar"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="@drawable/bg_avatar_placeholder" />
<!-- 官方标识 -->
<ImageView
android:id="@+id/ivOfficial"
android:layout_width="12dp"
android:layout_height="12dp"
android:src="@drawable/ic_official"
android:layout_alignTop="@id/ivAvatar"
android:layout_alignEnd="@id/ivAvatar" />
<!-- 标题 -->
<TextView
android:id="@+id/tvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="标题"
android:textSize="16sp"
android:textStyle="bold"
android:layout_toEndOf="@id/ivAvatar"
android:layout_marginStart="12dp"
android:layout_alignTop="@id/ivAvatar" />
<!-- 内容 -->
<TextView
android:id="@+id/tvContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="内容"
android:textSize="14sp"
android:textColor="#666666"
android:maxLines="1"
android:ellipsize="end"
android:layout_toEndOf="@id/ivAvatar"
android:layout_below="@id/tvTitle"
android:layout_marginStart="12dp"
android:layout_marginTop="4dp" />
<!-- 时间 -->
<TextView
android:id="@+id/tvTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="时间"
android:textSize="12sp"
android:textColor="#999999"
android:layout_alignParentEnd="true"
android:layout_alignTop="@id/tvTitle" />
<!-- 未读消息计数 -->
<TextView
android:id="@+id/tvUnreadCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="18dp"
android:background="@drawable/bg_unread_count"
android:textColor="@android:color/white"
android:textSize="10sp"
android:gravity="center"
android:layout_alignParentEnd="true"
android:layout_below="@id/tvTime"
android:layout_marginTop="4dp" />
</RelativeLayout>

@ -3,6 +3,18 @@
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<!-- 按钮颜色 -->
<color name="xianyu_yellow">#FFD700</color>
<color name="xianyu_yellow_dark">#FFC400</color>
<color name="xianyu_yellow_light">#FFE44D</color>
<!-- 文字颜色 -->
<color name="tab_text_normal">#666666</color>
<color name="tab_text_selected">#FFD700</color>
<!-- 其他颜色保持不变 -->
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="comui_tab_text_color">#ff333333</color>
</resources>

@ -1,11 +1,9 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<!--<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>-->
<item name="colorPrimary">@color/xianyu_yellow</item>
<item name="colorPrimaryDark">@color/xianyu_yellow_dark</item>
<item name="colorAccent">@color/xianyu_yellow</item>
</style>
</resources>

@ -1,15 +1,19 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
// Top-level build file where you can add configuration options common to all sub-projects/modules.
// Top-level build file where you can add configuration options common to all sub-projects/modules.
// project/build.gradle
buildscript {
ext.kotlin_version = '1.8.20' // 使 Kotlin
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.4.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
@ -18,8 +22,17 @@ allprojects {
google()
mavenCentral()
}
// 使 Kotlin
configurations.all {
resolutionStrategy {
force "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
force "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
force "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
}

@ -15,4 +15,7 @@
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# org.gradle.parallel=true
# gradle.properties
android.useAndroidX=true
android.enableJetifier=true

@ -1,6 +1,7 @@
#Sat Oct 11 19:07:18 CST 2025
# gradle-wrapper.properties
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.0-milestone-1-bin.zip
distributionUrl=https://mirrors.cloud.tencent.com/gradle/gradle-8.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

@ -1,23 +1,34 @@
apply plugin: 'com.android.library'
// mainnavigatetabbar/build.gradle
plugins {
id 'com.android.library'
}
android {
namespace "com.startsmake.mainnavigatetabbar"
compileSdkVersion 23
buildToolsVersion "23.0.1"
compileSdk 33
defaultConfig {
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "1.0"
minSdk 21
targetSdk 33
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:23.1.1'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.fragment:fragment:1.6.1'
// 使 Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.8.20"
}

@ -1,12 +1,9 @@
package com.startsmake.mainnavigatetabbar.widget;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.TypedValue;
@ -17,6 +14,16 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
// 删除旧的 Fragment 导入
// import android.app.Fragment;
// import android.app.FragmentTransaction;
// import android.support.v4.app.FragmentActivity;
// 添加 AndroidX Fragment 导入
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentTransaction;
import com.startsmake.mainnavigatetabbar.R;
import com.startsmake.mainnavigatetabbar.ThemeUtils;
@ -30,7 +37,7 @@ import java.util.List;
*/
public class MainNavigateTabBar extends LinearLayout implements View.OnClickListener {
private static final String KEY_CURRENT_TAG = "com.startsmake.templatecurrentTag";
private static final String KEY_CURRENT_TAG = "com.startsmake.template.currentTag";
private List<ViewHolder> mViewHolderList;
private OnTabSelectedListener mTabSelectListener;
@ -191,13 +198,14 @@ public class MainNavigateTabBar extends LinearLayout implements View.OnClickList
* @param holder
*/
private void showFragment(ViewHolder holder) {
FragmentTransaction transaction = mFragmentActivity.getFragmentManager().beginTransaction();
// 改为使用 Support FragmentManager
FragmentTransaction transaction = mFragmentActivity.getSupportFragmentManager().beginTransaction();
if (isFragmentShown(transaction, holder.tag)) {
return;
}
setCurrSelectedTabByTag(holder.tag);
Fragment fragment = mFragmentActivity.getFragmentManager().findFragmentByTag(holder.tag);
Fragment fragment = mFragmentActivity.getSupportFragmentManager().findFragmentByTag(holder.tag);
if (fragment == null) {
fragment = getFragmentInstance(holder.tag);
transaction.add(mMainContentLayoutId, fragment, holder.tag);
@ -217,7 +225,7 @@ public class MainNavigateTabBar extends LinearLayout implements View.OnClickList
return false;
}
Fragment fragment = mFragmentActivity.getFragmentManager().findFragmentByTag(mCurrentTag);
Fragment fragment = mFragmentActivity.getSupportFragmentManager().findFragmentByTag(mCurrentTag);
if (fragment != null && !fragment.isHidden()) {
transaction.hide(fragment);
}
@ -266,10 +274,11 @@ public class MainNavigateTabBar extends LinearLayout implements View.OnClickList
if (mViewHolderList == null || mViewHolderList.size() == 0) {
return;
}
FragmentTransaction transaction = mFragmentActivity.getFragmentManager().beginTransaction();
// 改为使用 Support FragmentManager
FragmentTransaction transaction = mFragmentActivity.getSupportFragmentManager().beginTransaction();
for (ViewHolder holder : mViewHolderList) {
Fragment fragment = mFragmentActivity.getFragmentManager().findFragmentByTag(holder.tag);
Fragment fragment = mFragmentActivity.getSupportFragmentManager().findFragmentByTag(holder.tag);
if (fragment != null && !fragment.isHidden()) {
transaction.hide(fragment);
}
@ -377,7 +386,4 @@ public class MainNavigateTabBar extends LinearLayout implements View.OnClickList
public int getCurrentSelectedTab(){
return mCurrentSelectedTab;
}
}
}
Loading…
Cancel
Save