用例文档 #2

Merged
p4vozqysr merged 4 commits from b_branch into develop 2 years ago

3
.idea/.gitignore vendored

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

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

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

@ -0,0 +1,15 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="11" />
</component>
</project>

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="11" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
</component>
</project>

@ -0,0 +1,88 @@
plugins {
id 'com.android.application'
id "org.sonarqube" version "3.3"
}
android {
namespace 'com.example.myapplication'
compileSdk 32
defaultConfig {
applicationId "com.example.myapplication"
minSdk 26
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures {
viewBinding true
}
}
apply plugin: "org.sonarqube"
sonarqube {
properties {
property "sonar.host.url", "http://localhost:9000" //sonar
property "sonar.login", "admin" // sonar
property "sonar.password", "YJL321432yjl" // sonar
property "sonar.sourceEncoding", "UTF-8"
property "sonar.projectKey", "poem" //sonarkey
property "sonar.projectName", "poem" //sonar
property "sonar.sources", "src/main" //sonar
property "sonar.projectVersion", project.version //
property "sonar.java.binaries", "build/intermediates/javac/debug/classes"
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'androidx.navigation:navigation-fragment:2.4.1'
implementation 'androidx.navigation:navigation-ui:2.4.1'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'com.github.xuexiangjys:XUI:1.2.1'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'com.github.bumptech.glide:glide:4.15.1'
/*步骤二添加retrofit依赖库*/
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'org.sufficientlysecure:html-textview:4.0'
//
implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.3'
// 使Header,
implementation 'com.scwang.smartrefresh:SmartRefreshHeader:1.1.3'
//tag
implementation 'com.hyman:flowlayout-lib:1.1.2'
//
// Charts
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
//
implementation 'com.tencent.edu:TAISDK:1.2.3.92'
//
implementation 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.3'
}

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

@ -0,0 +1,26 @@
package com.example.myapplication;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.example.myapplication", appContext.getPackageName());
}
}

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- 步骤一:添加网络权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<application
android:name=".XUIInit"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@drawable/app"
android:label="@string/app_name"
android:roundIcon="@drawable/app"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication"
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".Activity.RegisterActivity"
android:exported="false">
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
<activity
android:name=".Activity.MainActivity"
android:exported="false">
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
<activity
android:name=".Activity.AdviceActivity"
android:exported="false">
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
<activity
android:name=".Activity.DetailActivity"
android:exported="false">
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
<activity
android:name=".Activity.PoetryListActivity"
android:exported="false">
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
<activity
android:name=".Activity.TestActivity"
android:exported="false">
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
<activity
android:name=".Activity.ChatActivity"
android:exported="false">
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
<activity
android:name=".Activity.LoginActivity"
android:exported="true"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
</application>
</manifest>

@ -0,0 +1,36 @@
package com.example.myapplication.Activity;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
import com.example.myapplication.R;
import com.xuexiang.xui.widget.edittext.MultiLineEditText;
public class AdviceActivity extends AppCompatActivity {
private TextView poetryTitle;
private MultiLineEditText advice;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_advice);
Intent intent = getIntent();
String poetryId = intent.getStringExtra("poemId");
String Title = intent.getStringExtra("poemTitle");
String username = intent.getStringExtra("username");
initView();
poetryTitle.setText(Title);
}
private void initView() {
poetryTitle = findViewById(R.id.poetryTitle);
advice = findViewById(R.id.advice);
}
}

@ -0,0 +1,244 @@
package com.example.myapplication.Activity;
import static android.widget.Toast.LENGTH_SHORT;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.example.myapplication.Adapter.MsgAdapter;
import com.example.myapplication.Modal.ClientMessageBean;
import com.example.myapplication.Modal.SystemMessageBean;
import com.example.myapplication.R;
import com.example.myapplication.Util.FileUtils;
import com.example.myapplication.Util.WebSocketUtil;
import com.google.gson.Gson;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
public class ChatActivity extends AppCompatActivity {
private List<ClientMessageBean> msgList = new ArrayList<>();
private String username;
private int rid;
static int numOfCaches= 1;
//此处待修改
private String url = "ws://101.33.242.218:8081/chat/";
private EditText inputText;
private Button send;
private Button sendVoiceButton;
private ImageButton changeToVoice;
private ImageButton changeToText;
private RecyclerView msgRecyclerView;
private MsgAdapter adapter;
LinearLayout sendVoice;
LinearLayout sendText;
private LinearLayoutManager layoutManager;
private WebSocketUtil webSocketUtil;
//语音操作对象
private MediaPlayer mPlayer = null;
private MediaRecorder mRecorder = null;
//语音文件保存路径
private String FileName = null;
//接受消息,更新界面
private Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
SystemMessageBean systemMessageBean = (SystemMessageBean) message.obj;
Gson gson = new Gson();
ClientMessageBean messageBean ;
if(systemMessageBean.getFrom() == null){
messageBean = new ClientMessageBean(0,null,systemMessageBean.getMessage(),null);
}else if (!systemMessageBean.getFrom().equals(username)){
messageBean = gson.fromJson(systemMessageBean.getMessage(),ClientMessageBean.class);
messageBean.setType(messageBean.getType()+1);
}else{
messageBean = gson.fromJson(systemMessageBean.getMessage(),ClientMessageBean.class);
}
if(messageBean.getRecord()!=null){
try {
byte[] bytes = messageBean.getRecord();
FileUtils.getFileByBytes(bytes, getCacheDir().getPath()+"/",numOfCaches+".amr");
messageBean.setMessage(getCacheDir().getPath()+"/"+numOfCaches+".amr");
numOfCaches++;
}catch (Exception e){
e.printStackTrace();
}
}
msgList.add(messageBean);
//当有新消息刷新RecyclerVeiw的显示
adapter.notifyItemInserted(msgList.size() - 1);
//将RecyclerView定位到最后一行
msgRecyclerView.scrollToPosition(msgList.size() - 1);
//清空输入框内容
inputText.setText("");
return false;
}
});
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chat_view);
mPlayer = new MediaPlayer();
FileName = getCacheDir() + "/amrsend.amr";
//初始化控件
initView();
createConnection();
send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//点击发送后新建信息,发送给服务器
String content = inputText.getText().toString();
ClientMessageBean messageBean = new ClientMessageBean(
1,
username,
content,
null
);
Gson gson = new Gson();
webSocketUtil.send(gson.toJson(messageBean));
}
});
//切换发送语音和文本
changeToVoice.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sendText.setVisibility(View.GONE);
sendVoice.setVisibility(View.VISIBLE);
}
});
changeToText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sendVoice.setVisibility(View.GONE);
sendText.setVisibility(View.VISIBLE);
}
});
//设置发送语音监听
sendVoiceButton.setOnTouchListener(sendVoiceListener);
}
public void initView(){
sendText = findViewById(R.id.text_bottom);
sendVoice = findViewById(R.id.voice_bottom);
inputText = (EditText)findViewById(R.id.input_txet);
send = (Button) findViewById(R.id.send);
sendVoiceButton = findViewById(R.id.record_voice);
changeToVoice = findViewById(R.id.change_to_voice);
changeToText = findViewById(R.id.back_to_text);
//首先隐藏发送语音模块
sendVoice.setVisibility(View.GONE);
msgRecyclerView = (RecyclerView)findViewById(R.id.msg_recycle_view);
layoutManager = new LinearLayoutManager(this);
msgRecyclerView.setLayoutManager(layoutManager);
adapter = new MsgAdapter(msgList,mPlayer);
msgRecyclerView.setAdapter(adapter);
}
void createConnection(){
//获取进入房间号和用户名
Intent intent = getIntent();
username = intent.getStringExtra("username");
rid = intent.getIntExtra("rid",0);
webSocketUtil = new WebSocketUtil();
webSocketUtil.connect(url,rid,username,handler);
}
//这里记得断开连接
@Override
protected void onDestroy() {
super.onDestroy();
webSocketUtil.disconnect();
}
private OnTouchListener sendVoiceListener = new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
float beginX,beginY=0,finalX,finalY;
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
sendVoiceButton.setText("正在录音");
sendVoiceButton.setBackgroundColor(Color.RED);
beginX = motionEvent.getX();
beginY = motionEvent.getY();
Log.e("MainActivity", "beginX:" + beginX);
Log.e("MainActivity", "beginY:" + beginY);
Log.e("MainActivity", "ACTION_DOWN");
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(FileName);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
mRecorder.prepare();
} catch (IOException e) {
Log.e("MainActivity", "prepare() failed" + e);
}
mRecorder.start();
break;
case MotionEvent.ACTION_UP:
sendVoiceButton.setText("按住说话");
sendVoiceButton.setBackgroundColor(getColor(R.color.colorPrimaryDark));
finalX = motionEvent.getX();
finalY = motionEvent.getY();
Log.e("MainActivity", "finalX:" + finalX);
Log.e("MainActivity", "finalY:" + finalY);
Log.e("MainActivity", "ACTION_UP");
mRecorder.stop();
mRecorder.release();
mRecorder = null;
if ((beginY - finalY) > 50) {
Log.e("MainActivity", "执行删除");
new File(FileName).delete();
Toast.makeText( ChatActivity.this,"取消发送", LENGTH_SHORT).show();
Log.e("MainActivity", "执行删除后文件是否还存在:" + new File(FileName).exists());
}
if(new File(FileName).exists()){
ClientMessageBean messageBean = new ClientMessageBean(
3,
username,
null,
FileUtils.getBytesByFile(new File(FileName))
);
Gson gson = new Gson();
webSocketUtil.send(gson.toJson(messageBean));
}
break;
default:
break;
}
return true;
}
};
}

@ -0,0 +1,260 @@
package com.example.myapplication.Activity;
import static com.xuexiang.xui.XUI.getContext;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.StrictMode;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import com.example.myapplication.Api.Api;
import com.example.myapplication.Constant.constant;
import com.example.myapplication.Modal.PoetryDetail;
import com.example.myapplication.R;
import com.example.myapplication.Util.Spilt;
import com.google.gson.Gson;
import org.json.JSONException;
import org.json.JSONObject;
import org.sufficientlysecure.htmltextview.HtmlTextView;
import java.io.IOException;
import java.util.List;
import okhttp3.ResponseBody;
import retrofit2.Callback;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class DetailActivity extends AppCompatActivity {
private static final String TAG = "test";
private Retrofit PoetryDetailRetrofit;
private Context context;
private Toolbar toolbar;
private TextView titleText;
private String toolbarTitle;
private HtmlTextView htmlAnnotation;
private TextView translation;
private TextView appreciation;
private LinearLayout linearLayout;
private Button test_button;
private TextView menu_line;
private TextView poem_title;
private TextView poem_author;
private TextView poem_content;
private ImageView poem_menu_advice;
// 标签
// private TagFlowLayout tag_flow;
private ScrollView scrollView;
private ImageView author_img;
private ImageView icon_collect;
private TextView author_content;
private JSONObject responseObject;
private PoetryDetail poetryDetail;
private final int COMPLETED = 1;
private final int COLLECT = 2;
private final int STORAGE = 3;
private final int TO_WEBVIEW = 4;
private List<String> tags;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message message) {
if (message.what == COMPLETED) {
try {
poem_title.setText(poetryDetail.getTitle()); //诗词名
String author = poetryDetail.getDesty() + "." + poetryDetail.getAuthor();
poem_author.setText(author); //作者+朝代
String contentText = poetryDetail.getContent();
contentText = Spilt.spiltContentText(contentText);
poem_content.setText(contentText); //原文
// 图片
// Bitmap bitmap = getURLImage(poetryDetail.getImg()); //诗人图片
// author_img.setImageBitmap(bitmap);
// author_content.setText(poetryDetail.getAuthorDetail()); //诗人信息
String annotation = poetryDetail.getAnnotation();
htmlAnnotation.setHtml(annotation); //注释
appreciation.setText(poetryDetail.getAppreciation()); //赏析
translation.setText(poetryDetail.getTransContent()); //译文
// tags = spiltBySpace(poetryDetail.getTag()); //标签
// 标签
// initTagFlowLayout();
} catch (Exception e) {
e.printStackTrace();
}
}else {
Toast.makeText(DetailActivity.this, "显示失败", Toast.LENGTH_SHORT).show();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
context = getContext();
//在主线程访问网络连接
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
initView();
setSupportActionBar(toolbar);//设置toolbar
getSupportActionBar().setDisplayShowTitleEnabled(false);//屏蔽toolbar默认标题显示
toolbarTitle = getIntent().getStringExtra("toolbarTitle");
String content = getIntent().getStringExtra("content");
titleText.setText(toolbarTitle);
// 获取诗词详情
getPoetryDetailByContent(content);
// 监听器
//背诵
test_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent;
intent = new Intent(getContext(), TestActivity.class);
intent.putExtra("title", poetryDetail.getTitle());
intent.putExtra("desty", poetryDetail.getDesty());
intent.putExtra("author", poetryDetail.getAuthor());
intent.putExtra("content", poetryDetail.getContent());
startActivity(intent);
}
});
//意见反馈
poem_menu_advice.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getContext(), AdviceActivity.class);
String poemId = String.valueOf(poetryDetail.getId());
intent.putExtra("poemId", poemId);
intent.putExtra("poemTitle", poetryDetail.getTitle());
startActivity(intent);
}
});
}
private void initView() {
toolbar = findViewById(R.id.poem_titleBar);
titleText = findViewById(R.id.poem_titleText);
menu_line = findViewById(R.id.menu_line);
htmlAnnotation = findViewById(R.id.annotation_text);
translation = findViewById(R.id.translation_text);
appreciation = findViewById(R.id.appreciation_text);
test_button = findViewById(R.id.poem_test_button);
poem_title = findViewById(R.id.detail_poem_title);
poem_author = findViewById(R.id.detail_poem_author);
poem_content = findViewById(R.id.detail_poem_content);
poem_menu_advice = findViewById(R.id.poem_menu_advice);
author_img = findViewById(R.id.author_img);
author_content = findViewById(R.id.author_detail);
scrollView = findViewById(R.id.detail_scroll);
linearLayout = findViewById(R.id.poem_linnear);
icon_collect = findViewById(R.id.poem_menu_icon);
}
//根据首句获取诗词详情
public void getPoetryDetailByContent(String content) {
String poetry_detail_url = constant.poetry_IP;
//步骤五:构建Retrofit实例
PoetryDetailRetrofit = new Retrofit.Builder()
//设置网络请求BaseUrl地址
.baseUrl(poetry_detail_url)
//设置数据解析器
.addConverterFactory(GsonConverterFactory.create())
.build();
//步骤六:创建网络请求接口对象实例
Api poetryDetailApi = PoetryDetailRetrofit.create(Api.class);
//步骤七:对发送请求进行封装,传入接口参数
retrofit2.Call<ResponseBody> poetryDetailDataCall = poetryDetailApi.getPoetryDetail(content);
//步骤八:发送网络请求(同步)
Log.e(TAG, "get == url" + poetryDetailDataCall.request().url());
new Thread(new Runnable() { //Android主线程不能操作网络请求,所以new一个线程来操作
@Override
public void run() {
poetryDetailDataCall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(retrofit2.Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
try {
String responseData = response.body().string();
parseJSONWithGSON(responseData);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(retrofit2.Call<ResponseBody> call, Throwable t) {
Toast.makeText(DetailActivity.this, "获取诗词详情失败", Toast.LENGTH_SHORT).show();
}
});
}
}).start();
}
//解析返回数据
private void parseJSONWithGSON(String jsonData) {
Gson gson = new Gson();
JSONObject jsonObject = null;
try {
responseObject = new JSONObject(jsonData);
if (responseObject != null) {
jsonObject = responseObject;
}
} catch (JSONException e) {
e.printStackTrace();
}
PoetryDetail detail = null;
if (jsonObject != null) {//成功获取数据
detail = gson.fromJson(jsonObject.toString(), PoetryDetail.class);
poetryDetail = detail;
Message message = new Message();
message.what = COMPLETED;
handler.sendMessage(message);
} else//没有数据
{
Message message = new Message();
message.what = TO_WEBVIEW;
handler.sendMessage(message);
}
}
}

@ -0,0 +1,195 @@
package com.example.myapplication.Activity;
import androidx.appcompat.app.AppCompatActivity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.StrictMode;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.example.myapplication.Api.Api;
import com.example.myapplication.Constant.constant;
import com.example.myapplication.R;
import java.io.IOException;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class LoginActivity extends AppCompatActivity {
private static final String TAG = "test";
public static final int MSG_LOGIN_ERR = 1; //登录错误
public static final int MSG_CONNET_ERR = 2; //网络链接错误
private Context context;
private Retrofit LoginRetrofit;
private EditText et_number;
private EditText et_password;
private Button bt_login;
private Button bt_register;
private LoginHandler login_handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
context = this;
InitView();
login_handler = new LoginHandler();
Init();
// StrictMode是指严格模式
if (Build.VERSION.SDK_INT > 9){
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);//这两句设置禁止所有检查
}
}
private void InitView() {
et_number = (EditText)findViewById(R.id.et_number);
et_password = (EditText)findViewById(R.id.et_password);
bt_login = (Button)findViewById(R.id.bt_login);
bt_register = (Button) findViewById(R.id.bt_register);
}
private void Init() {
//设置提示的颜色
et_number.setHintTextColor(getResources().getColor(R.color.white));
et_password.setHintTextColor(getResources().getColor(R.color.white));
//登录
bt_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (judge()) {
loginInfo();
}
}
});
//注册
bt_register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(context, "注册", Toast.LENGTH_SHORT).show();
startActivity(new Intent(LoginActivity.this, RegisterActivity.class));
}
});
}
/**登录*/
private void loginInfo() {
String username = et_number.getText().toString();
String password = et_password.getText().toString();
String login_url = constant.poetry_IP;
//步骤五:构建Retrofit实例
LoginRetrofit = new Retrofit.Builder()
//设置网络请求BaseUrl地址
.baseUrl(login_url)
//设置数据解析器
.addConverterFactory(GsonConverterFactory.create())
.build();
//步骤六:创建网络请求接口对象实例
Api loginApi = LoginRetrofit.create(Api.class);
//步骤七:对发送请求进行封装,传入接口参数
Call<ResponseBody> loginDataCall = loginApi.getData(username, password);
//步骤八:发送网络请求(同步)
Log.e(TAG, "post == url" + loginDataCall.request().url());
new Thread(new Runnable() { //Android主线程不能操作网络请求,所以new一个线程来操作
@Override
public void run() {
loginDataCall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
String date = new String(response.body().bytes());
if(date.equals("success")){
Toast.makeText(LoginActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
}else{
Toast.makeText(LoginActivity.this, "登录失败,请检查你的用户名和密码", Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(LoginActivity.this, "get回调失败", Toast.LENGTH_SHORT).show();
}
});
}
}).start();
}
/**判断登录信息是否合法*/
private boolean judge() {
if (TextUtils.isEmpty(et_number.getText().toString()) ) {
Toast.makeText(context, "用户名不能为空",Toast.LENGTH_SHORT).show();
return false;
} else if (TextUtils.isEmpty(et_password.getText().toString())) {
Toast.makeText(context, "用户ID不能为空",Toast.LENGTH_SHORT).show();
return false;
}
return true;
}
/**事件捕获*/
class LoginHandler extends Handler {
@Override
public void dispatchMessage(Message msg) {
super.dispatchMessage(msg);
switch (msg.what) {
case MSG_LOGIN_ERR:
et_number.setText("");
et_password.setText("");
et_number.requestFocus();
new AlertDialog.Builder(LoginActivity.this)
.setTitle("注意")
.setMessage("用户名或密码输入不正确,请重新输入")
.setPositiveButton("确定",null)
.create()
.show();
bt_login.setEnabled(true);
break;
case MSG_CONNET_ERR:
new AlertDialog.Builder(LoginActivity.this)
.setTitle("注意")
.setMessage("网络连接错误,请检查网络")
.setPositiveButton("确定",null)
.create()
.show();
break;
}
}
}
}

@ -0,0 +1,155 @@
package com.example.myapplication.Activity;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import com.example.myapplication.Fragment.AiPoetry.AiPoetryFragment;
import com.example.myapplication.Fragment.My.MyFragment;
import com.example.myapplication.Fragment.Search.SearchFragment;
import com.example.myapplication.Fragment.association.AssociationFragment;
import com.example.myapplication.Fragment.home.HomeFragment;
import com.example.myapplication.R;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.fragment.app.FragmentTransaction;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import androidx.viewpager.widget.ViewPager;
import com.example.myapplication.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
BottomNavigationView navView;
ViewPager viewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//状态栏文字自适应
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
initViewPage();
initBottomNav();
FragmentManager manager = this.getSupportFragmentManager();
FragmentTransaction fTransaction = manager.beginTransaction();
fTransaction.replace(R.id.fragment_search,new SearchFragment());
fTransaction.commit();
}
/**
* viewPage
* viewPager
*/
private void initViewPage() {
viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) {
@NonNull
@Override
public Fragment getItem(int position) {
Fragment fragment = null;
/**
*positionposition
*/
switch ( position ){
case 0:
fragment = new HomeFragment();
break;
case 1:
fragment = new AiPoetryFragment();
break;
case 2:
requestPermission();
fragment = new AssociationFragment();
break;
case 3:
fragment = new MyFragment();
break;
}
assert fragment != null;
return fragment;
}
/**
*
*/
@Override
public int getCount() {
return 4;
}
});
//viewPager滑动事件监听
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
navView.getMenu().getItem(position).setChecked(true);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
/**
*
*/
private void initBottomNav() {
navView = findViewById(R.id.nav_view);
navView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
/**
*itemviewPagesetCurrentItem
*/
switch ( item.getItemId() ){
case R.id.navigation_home:
viewPager.setCurrentItem(0);
break;
case R.id.navigation_ai_poetry:
viewPager.setCurrentItem(1);
break;
case R.id.navigation_association:
viewPager.setCurrentItem(2);
break;
case R.id.navigation_my:
viewPager.setCurrentItem(3);
break;
}
return false;
}
});
}
private void requestPermission() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.RECORD_AUDIO)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.RECORD_AUDIO},
1234);
}
}
}

@ -0,0 +1,311 @@
package com.example.myapplication.Activity;
import static com.xuexiang.xui.XUI.getContext;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.example.myapplication.Adapter.PoemListAdapter;
import com.example.myapplication.Api.Api;
import com.example.myapplication.Constant.constant;
import com.example.myapplication.Modal.Poetry;
import com.example.myapplication.R;
import com.example.myapplication.Util.Spilt;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.listener.OnLoadMoreListener;
import com.scwang.smartrefresh.layout.listener.OnRefreshListener;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class PoetryListActivity extends AppCompatActivity {
private Retrofit SearchRetrofit;
private Retrofit SearchByTagRetrofit;
private static final String TAG = "test";
private PoemListAdapter poemListAdapter;
private ListView poemListView;
private Toolbar toolbar;
private TextView titleText;
private String toolbarTitle;
private final int COMPLETED = 1;
private final int TO_WEBVIEW = 2;
private RefreshLayout refreshLayout;
// 每次20首
private Integer size = 20;
private Integer page = 0;
private List<Poetry> poetryList = new ArrayList<>();
private boolean isLoad = false;
private JSONObject responseObject;
private String from;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message message) {
if (message.what == COMPLETED) { //绑定数据
try {
poemListAdapter = new PoemListAdapter(poetryList, getContext());
poemListView.setAdapter(poemListAdapter);
refreshLayout.finishRefresh();//结束刷新
refreshLayout.finishLoadMore(2000);//结束加载
isLoad = true;
} catch (Exception e) {
e.printStackTrace();
}
}
if (message.what == TO_WEBVIEW)//跳转至网站
{
Toast.makeText(getContext(), "暂时没有数据哦,请重新选择标签", Toast.LENGTH_LONG).show();
}
}
};
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
isLoad = false;
poetryList.clear();
break;
}
return true;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_poetry_list);
// 哪种搜索类型(搜索框/标签)
from = getIntent().getStringExtra("from");
toolbar = findViewById(R.id.titleBar);
poemListView = findViewById(R.id.poemList);
titleText = findViewById(R.id.titleText);
setSupportActionBar(findViewById(R.id.titleBar));//设置toolbar
refreshLayout = findViewById(R.id.refreshLayout);
refreshLayout.setEnableScrollContentWhenLoaded(true);
poemListAdapter = new PoemListAdapter(poetryList, getContext());
poemListView.setAdapter(poemListAdapter);
// poemListView.setEmptyView(findViewById(R.id.empty_imageview_iv));
getSupportActionBar().setDisplayShowTitleEnabled(false);//屏蔽toolbar默认标题显示
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.drawable.ic_back);
}//设置返回图标显示
toolbarTitle = getIntent().getStringExtra("toolBarTitle");
titleText.setText(toolbarTitle);
refreshLayout.autoRefresh();
refreshLayout.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh(RefreshLayout refreshlayout) {
if (from.equals("collect")) {
String temp = getIntent().getStringExtra("collect");
Log.d("TEMPPPPPPPPP", temp);
Gson gson = new Gson();
List<Poetry> poetries = gson.fromJson(temp, new TypeToken<List<Poetry>>() {
}.getType());
poetryList = poetries;
poemListAdapter = new PoemListAdapter(poetryList, getContext());
poemListView.setAdapter(poemListAdapter);
refreshlayout.finishRefresh();
} else if (from.equals("filter")) {
String tag = getIntent().getStringExtra("tag");
String dynasty = getIntent().getStringExtra("dynasty");
getPoemListByTag(tag, dynasty, page, size);
} else if (from.equals("search")) {
String key = getIntent().getStringExtra("key");
getPoemListBySearch(key, page, size);
} else if (from.equals("detail")) {
String tag = getIntent().getStringExtra("tag");
getPoemListByTag(tag, "null", page, size);
}
}
});
refreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() {
@Override
public void onLoadMore(RefreshLayout refreshlayout) {
if (from.equals("collect")) {
String temp = getIntent().getStringExtra("collect");
Log.d("TEMPPPPPPPPP", temp);
Gson gson = new Gson();
List<Poetry> poetries = gson.fromJson(temp, new TypeToken<List<Poetry>>() {
}.getType());
poetryList = poetries;
poemListAdapter = new PoemListAdapter(poetryList, getContext());
poemListView.setAdapter(poemListAdapter);
refreshlayout.finishRefresh();
refreshlayout.finishLoadMore(2000);
} else if (from.equals("filter")) {
page++;
String tag = getIntent().getStringExtra("tag");
String dynasty = getIntent().getStringExtra("dynasty");
getPoemListByTag(tag, dynasty, page, size);
} else if (from.equals("search")) {
page++;
String key = getIntent().getStringExtra("key");
getPoemListBySearch(key, page, size);
} else if (from.equals("detail")) {
page++;
String tag = getIntent().getStringExtra("tag");
getPoemListByTag(tag, "null", page, size);
}
}
});
poemListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(PoetryListActivity.this, DetailActivity.class);
String poemText = poetryList.get(position).getContent();
String sentence = Spilt.spiltPoemTextByEnter(poemText)[0];
intent.putExtra("content", sentence);
intent.putExtra("toolbarTitle", poetryList.get(position).getName());
startActivity(intent);
}
});
}
//根据标签获取诗词
private void getPoemListByTag(String tag, String dynasty, Integer page, Integer size) {
String searchByTag_url = constant.poetry_IP;
//步骤五:构建Retrofit实例
SearchByTagRetrofit = new Retrofit.Builder()
//设置网络请求BaseUrl地址
.baseUrl(searchByTag_url)
//设置数据解析器
.addConverterFactory(GsonConverterFactory.create())
.build();
//步骤六:创建网络请求接口对象实例
Api poetryApi = SearchByTagRetrofit.create(Api.class);
//步骤七:对发送请求进行封装,传入接口参数
retrofit2.Call<ResponseBody> poetryDataCall = poetryApi.getPoetrysByTag(dynasty, tag, page, size);
//步骤八:发送网络请求(同步)
Log.e(TAG, "post == url" + poetryDataCall.request().url());
new Thread(new Runnable() { //Android主线程不能操作网络请求,所以new一个线程来操作
@Override
public void run() {
poetryDataCall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(retrofit2.Call<ResponseBody> call, Response<ResponseBody> response) {
String responseData = null;
try {
responseData = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
parseJSONWithGSON(responseData);
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(PoetryListActivity.this, "get回调失败", Toast.LENGTH_SHORT).show();
}
});
}
}).start();
}
//根据搜索关键字获取诗词
private void getPoemListBySearch(String key, Integer page, Integer size) {
String search_url = constant.poetry_IP;
//步骤五:构建Retrofit实例
SearchRetrofit = new Retrofit.Builder()
//设置网络请求BaseUrl地址
.baseUrl(search_url)
//设置数据解析器
.addConverterFactory(GsonConverterFactory.create())
.build();
//步骤六:创建网络请求接口对象实例
Api poetryApi = SearchRetrofit.create(Api.class);
//步骤七:对发送请求进行封装,传入接口参数
retrofit2.Call<ResponseBody> poetryDataCall = poetryApi.getPoetrys(key, page, size);
//步骤八:发送网络请求(同步)
Log.e(TAG, "post == url" + poetryDataCall.request().url());
new Thread(new Runnable() { //Android主线程不能操作网络请求,所以new一个线程来操作
@Override
public void run() {
poetryDataCall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(retrofit2.Call<ResponseBody> call, Response<ResponseBody> response) {
String responseData = null;
try {
responseData = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
parseJSONWithGSON(responseData);
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(PoetryListActivity.this, "get回调失败", Toast.LENGTH_SHORT).show();
}
});
}
}).start();
}
private void parseJSONWithGSON(String jsonData) {
Gson gson = new Gson();
List<Poetry> list = gson.fromJson(jsonData, new TypeToken<List<Poetry>>(){}.getType());
if (list.size() != 0)//数据获取成功
{
poetryList.addAll(list);
Message message = new Message();
message.what = COMPLETED;
handler.sendMessage(message);
} else//没有数据
{
Message message = new Message();
message.what = TO_WEBVIEW;
handler.sendMessage(message);
}
}
}

@ -0,0 +1,196 @@
package com.example.myapplication.Activity;
import androidx.appcompat.app.AppCompatActivity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.StrictMode;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.example.myapplication.Api.Api;
import com.example.myapplication.Constant.constant;
import com.example.myapplication.R;
import java.io.IOException;
import okhttp3.FormBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RegisterActivity extends AppCompatActivity {
private static final String TAG = "test";
public static final int MSG_LOGIN_ERR = 1; //登录错误
public static final int MSG_CONNET_ERR = 2; //网络链接错误
private Context context;
private Retrofit RegisterRetrofit;
private EditText r_number;
private EditText r_password;
private Button bt_register;
private RegisterHandler register_handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
context = this;
InitView();
register_handler = new RegisterHandler();
Init();
// StrictMode是指严格模式
if (Build.VERSION.SDK_INT > 9){
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);//这两句设置禁止所有检查
}
}
private void InitView() {
r_number = (EditText)findViewById(R.id.r_number);
r_password = (EditText)findViewById(R.id.r_password);
bt_register = (Button)findViewById(R.id.bt_register);
}
private void Init() {
//设置提示的颜色
r_number.setHintTextColor(getResources().getColor(R.color.white));
r_password.setHintTextColor(getResources().getColor(R.color.white));
//注册
bt_register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (judge()) {
// postData();
registerInfo();
}
}
});
}
/**注册*/
private void registerInfo(){
String username = r_number.getText().toString();
String password = r_password.getText().toString();
String register_url = constant.poetry_IP;
//步骤五:创建Retrofit对象
RegisterRetrofit = new Retrofit.Builder()
.baseUrl(register_url) // 设置网络请求baseUrl
.addConverterFactory(GsonConverterFactory.create()) //设置使用Gson解析
.build();
// 步骤六:创建网络请求接口的实例
Api registerApi = RegisterRetrofit.create(Api.class);
//步骤七:对发送请求进行封装:传入参数
Call<ResponseBody> registerCall = registerApi.getRegisterData(username, password);
//步骤八:发送网络请求(异步)
Log.e(TAG, "post == url" + registerCall.request().url());
//请求参数
StringBuilder sb = new StringBuilder();
if (registerCall.request().body() instanceof FormBody) {
FormBody body = (FormBody) registerCall.request().body();
for (int i = 0; i < body.size(); i++) {
sb.append(body.encodedName(i))
.append(" = ")
.append(body.encodedValue(i))
.append(",");
}
sb.delete(sb.length() - 1, sb.length());
Log.e(TAG, "RequestParams:{" + sb.toString() + "}");
}
registerCall.enqueue(new Callback<ResponseBody>() {
//请求成功时回调
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
//步骤九:请求处理,输出结果
String date = null;
try {
date = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
if(date.equals("success")){
Toast.makeText(RegisterActivity.this, "注册成功", Toast.LENGTH_SHORT).show();
startActivity(new Intent(RegisterActivity.this, LoginActivity.class));
}else {
Toast.makeText(RegisterActivity.this, "注册失败,该用户名已被使用", Toast.LENGTH_SHORT).show();
}
}
//请求失败时回调
@Override
public void onFailure(Call<ResponseBody> call, Throwable throwable) {
Log.e(TAG, "post回调失败" + throwable.getMessage() + "," + throwable.toString());
Toast.makeText(RegisterActivity.this, "post回调失败", Toast.LENGTH_SHORT).show();
}
});
}
//判断登录信息是否合法
private boolean judge() {
if (TextUtils.isEmpty(r_number.getText().toString()) ) {
Toast.makeText(context, "用户名不能为空",Toast.LENGTH_SHORT).show();
return false;
} else if (TextUtils.isEmpty(r_password.getText().toString())) {
Toast.makeText(context, "用户ID不能为空",Toast.LENGTH_SHORT).show();
return false;
}
return true;
}
/**事件捕获*/
class RegisterHandler extends Handler {
@Override
public void dispatchMessage(Message msg) {
super.dispatchMessage(msg);
switch (msg.what) {
case MSG_LOGIN_ERR:
r_number.setText("");
r_password.setText("");
r_number.requestFocus();
new AlertDialog.Builder(RegisterActivity.this)
.setTitle("注意")
.setMessage("用户名或密码输入不正确,请重新输入")
.setPositiveButton("确定",null)
.create()
.show();
bt_register.setEnabled(true);
break;
case MSG_CONNET_ERR:
new AlertDialog.Builder(RegisterActivity.this)
.setTitle("注意")
.setMessage("网络连接错误,请检查网络")
.setPositiveButton("确定",null)
.create()
.show();
break;
}
}
}
}

@ -0,0 +1,398 @@
package com.example.myapplication.Activity;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Bundle;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.example.myapplication.Api.ToTrans;
import com.example.myapplication.Modal.EmotionResBean;
import com.example.myapplication.Modal.PrivateInfo;
import com.example.myapplication.R;
import com.example.myapplication.Util.Spilt;
import com.github.mikephil.charting.charts.HorizontalBarChart;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.formatter.IndexAxisValueFormatter;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.tencent.taisdk.TAIError;
import com.tencent.taisdk.TAIOralEvaluation;
import com.tencent.taisdk.TAIOralEvaluationData;
import com.tencent.taisdk.TAIOralEvaluationEvalMode;
import com.tencent.taisdk.TAIOralEvaluationFileType;
import com.tencent.taisdk.TAIOralEvaluationListener;
import com.tencent.taisdk.TAIOralEvaluationParam;
import com.tencent.taisdk.TAIOralEvaluationRet;
import com.tencent.taisdk.TAIOralEvaluationServerType;
import com.tencent.taisdk.TAIOralEvaluationStorageMode;
import com.tencent.taisdk.TAIOralEvaluationTextMode;
import com.tencent.taisdk.TAIOralEvaluationWord;
import com.tencent.taisdk.TAIOralEvaluationWorkMode;
import com.tencent.taisdk.TAIRecorderParam;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class TestActivity extends AppCompatActivity {
TAIOralEvaluation oralEvaluation ;
TextView content;
TextView author;
TextView title;
TextView oralResult;
Button viewAns ;
TAIOralEvaluationParam param;
String[] criterion = {"评分标准","发音标准","流利度","发音完整度"};
HorizontalBarChart ratings ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
requestPermission();
initView();
settingsOfChat();
setPoem();
ratings.setVisibility(View.INVISIBLE);
//点击查看答案,显示诗句内容
viewAns.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
content.setVisibility(View.VISIBLE);
}
});
}
public void onRecord(View view){
Button button = (Button) view;
oralResult.setText("");
if(oralEvaluation == null){
oralEvaluation = new TAIOralEvaluation();
}
if (oralEvaluation.isRecording()){
button.setText("开始测试");
oralEvaluation.stopRecordAndEvaluation();
}else {
button.setText("停止录制");
oralEvaluation.setListener(new TAIOralEvaluationListener() {
@Override
public void onEvaluationData(TAIOralEvaluationData data, TAIOralEvaluationRet result) {
/**
*
* result
*/
System.out.println("middle");
}
@Override
public void onEvaluationError(TAIOralEvaluationData data, TAIError error) {
//调用接口失败,提升信号不好或账号已欠费
System.out.println("error");
runOnUiThread(new Runnable() {
@Override
public void run() {
Gson gson = new Gson();
String retString = gson.toJson(error);
String errorStr = "onEvaluationE rror: " + retString + " seqId: " + data.seqId;
}
});
}
@Override
public void onFinalEvaluationData(TAIOralEvaluationData data, TAIOralEvaluationRet result) {
//提交服务端,情感分析
submitMp3(param.audioPath);
/**
*
*
*/
List<TAIOralEvaluationWord> list = result.words;
String text = String.valueOf(content.getText());
//部分文字改变颜色
//这里注意一定要先给textview赋值
SpannableStringBuilder builder = new SpannableStringBuilder(text);
int curr = 0,size = text.length();
for (TAIOralEvaluationWord word : list) {
/**
* -1
* <0.5 || 0.7
*/
ForegroundColorSpan miss = new ForegroundColorSpan(getResources().getColor(R.color.toast_error_color));
ForegroundColorSpan worry = new ForegroundColorSpan(getResources().getColor(R.color.toast_error_color));
ForegroundColorSpan right = new ForegroundColorSpan(getResources().getColor(R.color.black));
if(word.pronAccuracy <= -1){
builder.setSpan(miss,curr,curr+1, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
}else if(word.pronAccuracy <= 0.5){
builder.setSpan(worry,curr,curr+1, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
}else {
builder.setSpan(right,curr,curr+1, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
}
curr++;
while(curr < text.length() && isChinesePunctuation(text.charAt(curr))){
curr++;
}
}
/**
*
*/
Gson gson = new Gson();
String retString = gson.toJson(result);
String ans = "";
JsonParser parser = new JsonParser();
JsonElement JsonTree = parser.parse(retString);
double SuggestedScore,PronAccuracy = 0,PronFluency = 0,PronCompletion = 0;
if(JsonTree.isJsonObject()){
JsonObject jsonObject = JsonTree.getAsJsonObject();
SuggestedScore = jsonObject.get("SuggestedScore").getAsDouble();
ans += "评分: "+SuggestedScore+"\n";
PronAccuracy = jsonObject.get("PronAccuracy").getAsDouble();
// ans += "PronAccuracy: "+PronAccuracy+"\n";
PronFluency = jsonObject.get("PronFluency").getAsDouble();
// ans += "PronFluency: "+PronFluency+"\n";
PronCompletion = jsonObject.get("PronCompletion").getAsDouble();
// ans += "PronCompletion: "+PronCompletion+"\n";
}
String finalAns = ans;
int finalPronAccuracy = (int) (PronAccuracy);
int finalPronFluency = (int) (PronFluency*100);
int finalPronCompletion = (int) (PronCompletion*100);
runOnUiThread(new Runnable() {
@Override
public void run() {
//图表设置
List<BarEntry>list=new ArrayList<>();
list.add(new BarEntry(1, finalPronAccuracy));
list.add(new BarEntry(2, finalPronFluency));
list.add(new BarEntry(3, finalPronCompletion));
BarDataSet barDataSet=new BarDataSet(list,"口语分析");
BarData barData=new BarData(barDataSet);
barData.setDrawValues(true);
ratings.setVisibility(View.VISIBLE);
ratings.setData(barData);
ratings.animateY(3000);
content.setText(builder);
content.setVisibility(View.VISIBLE);
oralResult.append(finalAns);
// oralResult.append(retString);
}
});
}
@Override
public void onEndOfSpeech(boolean isSpeak) {
runOnUiThread(new Runnable() {
@Override
public void run() {
onRecord(null);
}
});
}
@Override
public void onVolumeChanged(int volume) {
;
}
});
param = new TAIOralEvaluationParam();
param.context = this;
param.sessionId = UUID.randomUUID().toString();
param.appId = PrivateInfo.appId;
param.soeAppId = PrivateInfo.soeAppId;
param.secretId = PrivateInfo.secretId;
param.secretKey = PrivateInfo.secretKey;
param.token = PrivateInfo.token;
int evalMode = TAIOralEvaluationEvalMode.PARAGRAPH;
param.workMode = TAIOralEvaluationWorkMode.ONCE ;
param.evalMode = evalMode;
param.storageMode = TAIOralEvaluationStorageMode.DISABLE;
param.fileType = TAIOralEvaluationFileType.MP3;
param.serverType = TAIOralEvaluationServerType.CHINESE ;
param.textMode = TAIOralEvaluationTextMode.NORMAL ;
param.scoreCoeff = 2.0;
param.refText = content.getText().toString();
param.audioPath = this.getFilesDir() + "/" + param.sessionId + ".mp3";
if (param.workMode == TAIOralEvaluationWorkMode.STREAM) {
param.timeout = 5;
param.retryTimes = 5;
} else {
param.timeout = 30;
param.retryTimes = 0;
}
TAIRecorderParam recordParam = new TAIRecorderParam();
recordParam.fragSize = (int) (1.0 * 1024);
recordParam.fragEnable = false;
recordParam.vadEnable = true;
recordParam.vadInterval = Integer.parseInt("5000");
oralEvaluation.setRecorderParam(recordParam);
oralEvaluation.startRecordAndEvaluation(param);
}
}
private void requestPermission() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.RECORD_AUDIO)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.RECORD_AUDIO},
1234);
}
}
public boolean isChinesePunctuation(char c) {
Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
if (ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS
|| ub == Character.UnicodeBlock.VERTICAL_FORMS) {
return true;
} else {
return false;
}
}
void submitMp3(String filePath){
File file = new File(filePath);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://101.33.242.218:8081")
.addConverterFactory(GsonConverterFactory.create())
.build();
ToTrans request = retrofit.create(ToTrans.class);
//请求体
MultipartBody.Builder builder = new MultipartBody.Builder()
.setType(MultipartBody.FORM);
RequestBody requestBody = RequestBody.create(MediaType.parse("audio/mpeg"),file);
builder.addFormDataPart("file", file.getName(), requestBody);
List<MultipartBody.Part> parts = builder.build().parts();
//对 发送请求 进行封装
Call<EmotionResBean> call = request.getCall(parts);
call.enqueue(new Callback<EmotionResBean>() {
//请求成功时回调
@Override
public void onResponse(Call<EmotionResBean> call, Response<EmotionResBean> response) {
//请求处理,输出结果
System.out.println(response.body());
Gson gson = new Gson();
EmotionResBean resBean = response.body();
String emotion = resBean.getEmotion();
if(emotion.equals("neutral")||emotion.equals("calm")) {
oralResult.append("看看赏析,再体会诗中的情感");
}else {
oralResult.append("声情并茂呢");
}
}
//请求失败时候的回调
@Override
public void onFailure(Call<EmotionResBean> call, Throwable throwable) {
System.out.println((call.request().body()));
System.out.println("连接失败");
}
});
}
void initView(){
content = findViewById(R.id.content);
oralResult = findViewById(R.id.result);
ratings = findViewById(R.id.ratings);
viewAns = findViewById(R.id.viewAns);
title = findViewById(R.id.title);
author = findViewById(R.id.author);
//设置内容不可见
content.setVisibility(View.INVISIBLE);
}
void settingsOfChat(){
//X轴
XAxis xAxis=ratings.getXAxis();
xAxis.setDrawGridLines(false); //是否绘制X轴上的网格线背景里面的竖线
xAxis.setAxisLineColor(Color.BLACK); //X轴颜色
xAxis.setAxisLineWidth(2); //X轴粗细
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); //X轴所在位置 默认为上面
xAxis.setValueFormatter(new IndexAxisValueFormatter(criterion));
xAxis.setAxisMaximum(4); //X轴最大数值
xAxis.setAxisMinimum(0); //X轴最小数值
//X轴坐标的个数 第二个参数一般填false true表示强制设置标签数 可能会导致X轴坐标显示不全等问题
xAxis.setLabelCount(4,false);
xAxis.setAvoidFirstLastClipping(true);
//Y轴
YAxis AxisLeft=ratings.getAxisRight();
AxisLeft.setDrawGridLines(false); //是否绘制Y轴上的网格线背景里面的横线
AxisLeft.setAxisLineColor(Color.BLACK); //Y轴颜色
AxisLeft.setAxisLineWidth(2); //Y轴粗细
// AxisLeft.setValueFormatter(new DefaultAxisValueFormatter(100));
AxisLeft.setAxisMaximum(105f); //Y轴最大数值
AxisLeft.setAxisMinimum(0f); //Y轴最小数值
//Y轴坐标的个数 第二个参数一般填false true表示强制设置标签数 可能会导致X轴坐标显示不全等问题
AxisLeft.setLabelCount(5,false);
AxisLeft=ratings.getAxisLeft();
AxisLeft.setDrawGridLines(false); //是否绘制Y轴上的网格线背景里面的横线
AxisLeft.setAxisLineColor(Color.BLACK); //Y轴颜色
AxisLeft.setAxisLineWidth(2); //Y轴粗细
// AxisLeft.setValueFormatter(new DefaultAxisValueFormatter(100));
AxisLeft.setAxisMaximum(105f); //Y轴最大数值
AxisLeft.setAxisMinimum(0f); //Y轴最小数值
//Y轴坐标的个数 第二个参数一般填false true表示强制设置标签数 可能会导致X轴坐标显示不全等问题
AxisLeft.setLabelCount(5,false);
//是否隐藏右边的Y轴不设置的话有两条Y轴 同理可以隐藏左边的Y轴
ratings.getDescription().setEnabled(false);//隐藏右下角英文
ratings.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM);//X轴的位置 默认为右边
ratings.getAxisLeft().setEnabled(false);//隐藏上侧Y轴 默认是上下两侧都有Y轴
ratings.setTouchEnabled(false);//不可调整大小
}
void setPoem(){
//获取活动跳转传过来的诗,并显示在界面(诗内容不显示)
Intent intent = getIntent();
title.setText(intent.getStringExtra("title"));
String dynasty_author = intent.getStringExtra("desty") + " . "
+ intent.getStringExtra("author");
author.setText(dynasty_author);
String contentText = intent.getStringExtra("content");
contentText = Spilt.spiltContentText(contentText);
content.setText(contentText);
}
}

@ -0,0 +1,151 @@
package com.example.myapplication.Adapter;
import android.media.MediaPlayer;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.example.myapplication.Modal.ClientMessageBean;
import com.example.myapplication.Modal.SystemMessageBean;
import com.example.myapplication.R;
import java.io.File;
import java.io.IOException;
import java.util.List;
public class MsgAdapter extends RecyclerView.Adapter<MsgAdapter.ViewHolder> {
private List<ClientMessageBean> mMsgList;
private MediaPlayer mPlayer;
static class ViewHolder extends RecyclerView.ViewHolder{
LinearLayout leftLayout;
LinearLayout rightLayout;
LinearLayout centerLayout;
LinearLayout voiceRightLayout;
LinearLayout voiceLeftLayout;
TextView leftMsg;
TextView rightMsg;
TextView centerMsg;
ImageButton broadcastRight;
ImageButton broadcastLeft;
public ViewHolder(View view){
super(view);
leftLayout = view.findViewById(R.id.left_layout);
rightLayout = view.findViewById(R.id.right_layout);
centerLayout = view.findViewById(R.id.center_layout);
leftMsg = view.findViewById(R.id.left_msg);
rightMsg = view.findViewById(R.id.right_msg);
centerMsg = view.findViewById(R.id.center_msg);
voiceLeftLayout = view.findViewById(R.id.voice_order);
voiceRightLayout = view.findViewById(R.id.voice_self);
broadcastLeft = view.findViewById(R.id.record_order);
broadcastRight = view.findViewById(R.id.record_self);
}
}
public MsgAdapter(List<ClientMessageBean> msgList, MediaPlayer mPlayer){
mMsgList = msgList;
this.mPlayer = mPlayer;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.message_view,parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder,int position){
ClientMessageBean msg = mMsgList.get(position);
if (msg.getType() == 2){
//如果收到消息,则显示在左边,将右边,中间布局隐藏
holder.leftLayout.setVisibility(View.VISIBLE);
holder.centerLayout.setVisibility(View.GONE);
holder.rightLayout.setVisibility(View.GONE);
//语音隐藏
holder.voiceRightLayout.setVisibility(View.GONE);
holder.voiceLeftLayout.setVisibility(View.GONE);
holder.leftMsg.setText(msg.getMessage());
}else if(msg.getType() == 1){
//将左,中布局隐藏
holder.rightLayout.setVisibility(View.VISIBLE);
holder.centerLayout.setVisibility(View.GONE);
holder.leftLayout.setVisibility(View.GONE);
holder.voiceRightLayout.setVisibility(View.GONE);
holder.voiceLeftLayout.setVisibility(View.GONE);
holder.rightMsg.setText(msg.getMessage());
}else if(msg.getType() == 0){
//隐藏左右布局
holder.centerLayout.setVisibility(View.VISIBLE);
holder.leftLayout.setVisibility(View.GONE);
holder.rightLayout.setVisibility(View.GONE);
holder.voiceRightLayout.setVisibility(View.GONE);
holder.voiceLeftLayout.setVisibility(View.GONE);
holder.centerMsg.setText(msg.getMessage());
} else if (msg.getType() == 3) {
holder.leftLayout.setVisibility(View.GONE);
holder.rightLayout.setVisibility(View.GONE);
holder.centerLayout.setVisibility(View.GONE);
holder.voiceRightLayout.setVisibility(View.VISIBLE);
holder.voiceLeftLayout.setVisibility(View.GONE);
try {
holder.broadcastRight.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
try {
mPlayer.reset();
mPlayer.setDataSource(msg.getMessage());
mPlayer.prepare();
} catch (IOException e) {
throw new RuntimeException(e);
}
mPlayer.start();
}
}).start();
}
});
} catch (Exception e) {
throw new RuntimeException(e);
}
} else if (msg.getType() == 4) {
holder.leftLayout.setVisibility(View.GONE);
holder.rightLayout.setVisibility(View.GONE);
holder.centerLayout.setVisibility(View.GONE);
holder.voiceRightLayout.setVisibility(View.GONE);
holder.voiceLeftLayout.setVisibility(View.VISIBLE);
try {
holder.broadcastRight.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
try {
mPlayer.reset();
mPlayer.setDataSource(msg.getMessage());
mPlayer.prepare();
} catch (IOException e) {
throw new RuntimeException(e);
}
mPlayer.start();
}
}).start();
}
});
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
@Override
public int getItemCount(){
return mMsgList.size();
}
}

@ -0,0 +1,75 @@
package com.example.myapplication.Adapter;
import android.content.Context;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.example.myapplication.R;
import com.example.myapplication.Modal.Poetry;
import com.example.myapplication.Util.Spilt;
import java.util.ArrayList;
import java.util.List;
public class PoemListAdapter extends BaseAdapter {
private List<Poetry> poetryList = new ArrayList<Poetry>();
private Context context;
public PoemListAdapter(List<Poetry> poetryList, Context context) {
this.poetryList = poetryList;
this.context = context;
}
@Override
public int getCount() {
return poetryList.size();
}
@Override
public Object getItem(int position) {
return poetryList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
Log.d("ListViewLoading", "--------------------------------------------");
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = View.inflate(context, R.layout.poem_item, null);
viewHolder.author = convertView.findViewById(R.id.poem_author);
viewHolder.title = convertView.findViewById(R.id.poem_title);
viewHolder.contentView = convertView.findViewById(R.id.poem_content);
viewHolder.spiltLine = convertView.findViewById(R.id.spilt_line);
convertView.setTag(viewHolder);
} else
viewHolder = (ViewHolder) convertView.getTag();
viewHolder.title.setText(poetryList.get(position).getName());
String author = poetryList.get(position).getDynasty() + "." + poetryList.get(position).getAuthor();
viewHolder.author.setText(author);
String content = poetryList.get(position).getContent();
content = Spilt.spiltContentText(content);
viewHolder.contentView.setText(content);
return convertView;
}
public class ViewHolder {
public TextView title;
public TextView author;
public TextView contentView;
public TextView spiltLine;
}
}

@ -0,0 +1,67 @@
package com.example.myapplication.Adapter;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.myapplication.Activity.ChatActivity;
import com.example.myapplication.Modal.RoomBean;
import com.example.myapplication.R;
import java.util.List;
public class RoomAdapter extends RecyclerView.Adapter<RoomAdapter.ViewHolder>{
List<RoomBean> mRoomList ;
Context mContext;
static class ViewHolder extends RecyclerView.ViewHolder{
TextView rname;
TextView description;
public ViewHolder(View view){
super(view);
rname = view.findViewById(R.id.rname);
description = view.findViewById(R.id.description);
}
}
public RoomAdapter(List<RoomBean> list,Context context){
this.mRoomList = list;
this.mContext = context;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.room_view,parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
RoomBean roomBean = mRoomList.get(position);
holder.rname.setText(roomBean.getRname());
holder.description.setText(roomBean.getDescription());
View.OnClickListener listener = new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(mContext, ChatActivity.class);
//用户名还需要调整
intent.putExtra("username", String.valueOf(Math.random()));
intent.putExtra("rid", roomBean.getRid());
mContext.startActivity(intent);
}
};
holder.description.setOnClickListener(listener);
holder.rname.setOnClickListener(listener);
}
@Override
public int getItemCount() {
return mRoomList.size();
}
}

@ -0,0 +1,53 @@
package com.example.myapplication.Api;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;
/**
* @
* @ 2023/5/31 17:44
* @ ${TODO}(Url)
*/
public interface Api {
//这里特别说明Url的组成retrofit把网络请求的Url分成两部分设置第一部分在创建Retrofit实例时通过.baseUrl()设置,
//第二部分在网络接口注解中设置,如下面的"/user"网络请求的完整地址Url = Retrofit实例.baseUrl()+网络请求接口注解()
@GET("user/loginIn")
Call<ResponseBody> getData(@Query("username") String username, @Query("password") String password);
@GET("user/register")
Call<ResponseBody> getRegisterData(@Query("username") String username, @Query("password") String password);
@GET("poetry/getOnePoem")
Call<ResponseBody> getPoetry();
@GET("poetry/getByContentDetail")
Call<ResponseBody> getPoetryDetail(@Query("content") String content);
@GET("poetry/getBySearch")
Call<ResponseBody> getPoetrys(@Query("key") String key, @Query("page") Integer page, @Query("size") Integer size);
@GET("poetry/getAllDynasty")
Call<ResponseBody> getDynastyList();
@GET("poetry/getByTag")
Call<ResponseBody> getPoetrysByTag(@Query("dynasty") String dynasty, @Query("tag") String tag, @Query("page") Integer page, @Query("size") Integer size);
@GET("poetry/generate")
Call<ResponseBody> createPoetry(@Query("form") String form, @Query("head") String head);
//post请求
@FormUrlEncoded
@POST("api/comments.163")
Call<Object> postDataCall(@Field("format") String format);
@FormUrlEncoded
@POST("user/register")
Call<Object> registerCall(@Field("username") String username, @Field("password") String password);
}

@ -0,0 +1,22 @@
package com.example.myapplication.Api;
import com.example.myapplication.Modal.EmotionResBean;
import java.util.List;
import okhttp3.MultipartBody;
import retrofit2.Call;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;
public interface ToTrans {
@Multipart
@POST("/poetry/emotion")
Call<EmotionResBean> getCall(@Part List<MultipartBody.Part> partList);
// @GET注解的作用:采用Get方法发送网络请求
// getCall() = 接收网络请求数据的方法
// 其中返回类型为Call<*>*是接收数据的类即上面定义的TranslationBean类返回这个类的对象
}

@ -0,0 +1,6 @@
package com.example.myapplication.Constant;
public class constant {
public static final String poetry_IP = "http://101.33.242.218:8081/";
}

@ -0,0 +1,243 @@
package com.example.myapplication.Fragment.AiPoetry;
import android.graphics.Color;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.example.myapplication.Api.Api;
import com.example.myapplication.Constant.constant;
import com.example.myapplication.Modal.PoetryUtil;
import com.example.myapplication.R;
import com.example.myapplication.databinding.FragmentAiPoetryBinding;
import com.example.myapplication.Util.Spilt;
import com.xuexiang.xui.widget.edittext.materialedittext.MaterialEditText;
import com.zhy.view.flowlayout.FlowLayout;
import com.zhy.view.flowlayout.TagAdapter;
import com.zhy.view.flowlayout.TagFlowLayout;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import okhttp3.ResponseBody;
import retrofit2.Callback;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class AiPoetryFragment extends Fragment {
private FragmentAiPoetryBinding binding;
private static final String TAG = "test";
private Retrofit CreateRetrofit;
private Button startButton;
private MaterialEditText inputText;
private TextView createdText;
private TagFlowLayout poem_tag_flow;
private List<String> poem_tags;
private TagFlowLayout poem_style_flow;
private HashMap<String, String> poem_type;
private HashMap<String, String> poem_style;
private HashMap<String, String> selectedTag = new HashMap<>();
private List<String> styles;
private String createdPoem = "";
private final int GET_POEM_FAIL = 0;
private final int GET_POEM_SUCCESS = 1;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message message) {
if (message.what == GET_POEM_SUCCESS) {
String contentText = Spilt.spiltContentText(createdPoem);
createdText.setText(contentText);
}
if (message.what == GET_POEM_FAIL) {
createdText.setText(" ");
Toast.makeText(getContext(), "服务错误,请重试", Toast.LENGTH_LONG).show();
}
}
};
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentAiPoetryBinding.inflate(inflater, container, false);
View root = binding.getRoot();
initView();//初始化视图
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
createdText.setText("加载中...");
String form = selectedTag.get("yan") + selectedTag.get("type");
String head = inputText.getEditValue();
String create_url = constant.poetry_IP;
//步骤五:构建Retrofit实例
CreateRetrofit = new Retrofit.Builder()
//设置网络请求BaseUrl地址
.baseUrl(create_url)
//设置数据解析器
.addConverterFactory(GsonConverterFactory.create())
.build();
//步骤六:创建网络请求接口对象实例
Api createApi = CreateRetrofit.create(Api.class);
//步骤七:对发送请求进行封装,传入接口参数
retrofit2.Call<ResponseBody> createDataCall = createApi.createPoetry(form,head);
//步骤八:发送网络请求(同步)
Log.e(TAG, "get == url" + createDataCall.request().url());
new Thread(new Runnable() { //Android主线程不能操作网络请求,所以new一个线程来操作
@Override
public void run() {
createDataCall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(retrofit2.Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
String responseData = null;
try {
responseData = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
createdPoem = responseData;
Message message = new Message();
message.what = GET_POEM_SUCCESS;
handler.sendMessage(message);
}
@Override
public void onFailure(retrofit2.Call<ResponseBody> call, Throwable t) {
t.printStackTrace();
Message message = new Message();
message.what = GET_POEM_FAIL;
handler.sendMessage(message);
}
});
}
}).start();
}
});
return root;
}
private void initView() {
poem_tags = PoetryUtil.getPoemTags();
poem_type = PoetryUtil.getPoemType();
poem_style = PoetryUtil.getPoemStyle();
styles = PoetryUtil.getStyles();
poem_tag_flow = binding.aiPoemTagFlow;
poem_style_flow = binding.aiStyleTagFlow;
inputText = binding.inputKeyword;
startButton = binding.creatingButton;
createdText = binding.createdContent;
final LayoutInflater mInflater = getLayoutInflater();
poem_tag_flow.setAdapter(new TagAdapter<String>(poem_tags) {
@Override
public View getView(FlowLayout parent, int position, String s) {
TextView tv = (TextView) mInflater.inflate(R.layout.adapter_item_tag,
poem_tag_flow, false);
tv.setText(s);
return tv;
}
@Override
public void onSelected(int position, View view) {
super.onSelected(position, view);
selectedTag.put("type", poem_type.get(poem_tags.get(position)));
TextView textView = (TextView) view;
textView.setTextColor(Color.WHITE);
}
@Override
public void unSelected(int position, View view) {
super.unSelected(position, view);
TextView textView = (TextView) view;
selectedTag.remove("type");
showSelected(selectedTag);
textView.setTextColor(getResources().getColor(R.color.colorPrimary));
}
});
poem_style_flow.setAdapter(new TagAdapter<String>(styles) {
@Override
public View getView(FlowLayout parent, int position, String s) {
TextView tv = (TextView) mInflater.inflate(R.layout.adapter_item_tag,
poem_style_flow, false);
tv.setText(s);
return tv;
}
@Override
public void onSelected(int position, View view) {
super.onSelected(position, view);
selectedTag.put("yan", poem_style.get(styles.get(position)).toString());
TextView textView = (TextView) view;
textView.setTextColor(Color.WHITE);
}
@Override
public void unSelected(int position, View view) {
super.unSelected(position, view);
TextView textView = (TextView) view;
selectedTag.remove("yan");
textView.setTextColor(getResources().getColor(R.color.colorPrimary));
}
});
}
private void showSelected(HashMap<String, String> temp) {
if (temp.size() > 0) {
for (String tempString : temp.keySet())
System.out.println(tempString + ": " + temp.get(tempString));
} else
System.out.println("没有选择");
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

@ -0,0 +1,32 @@
package com.example.myapplication.Fragment.My;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import com.example.myapplication.databinding.FragmentMyBinding;
import com.xuexiang.xui.widget.textview.supertextview.SuperTextView;
public class MyFragment extends Fragment {
private FragmentMyBinding binding;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
binding = FragmentMyBinding.inflate(inflater, container, false);
View root = binding.getRoot();
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

@ -0,0 +1,222 @@
package com.example.myapplication.Fragment.Search;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.example.myapplication.Activity.PoetryListActivity;
import com.example.myapplication.Modal.PoetryUtil;
import com.example.myapplication.R;
import com.example.myapplication.databinding.FragmentAssociationBinding;
import com.example.myapplication.databinding.FragmentSearchBinding;
import com.zhy.view.flowlayout.FlowLayout;
import com.zhy.view.flowlayout.TagAdapter;
import com.zhy.view.flowlayout.TagFlowLayout;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class SearchFragment extends Fragment {
private FragmentSearchBinding binding;
private static final String TAG = "test";
private Button sureButton;
private final int COMPLETED = 1;
private final int RESPONSE_SUCCESS = 2;
private final int RESPONSE_FAIL = 0;
private final int TO_WEBVIEW = 3;
private JSONObject poetryObject;
private JSONArray collectObject;
private TagFlowLayout typeTagLayout;
private TagFlowLayout dynastyTagLayout;
private TagFlowLayout styleTagLayout;
private String[] typeList = null;
private String[] dynastyList = null;
private String[] styleList = null;
private List<String> selectedType = new ArrayList<String>();
private List<String> selectedStyle = new ArrayList<String>();
private List<String> selectedDynasty = new ArrayList<String>();
public SearchFragment() {}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentSearchBinding.inflate(inflater, container, false);
View root = binding.getRoot();
initView();//初始化视图
//将标签数据传递给下一页面
sureButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent;
intent = new Intent(getContext(), PoetryListActivity.class);
String tag = "";
String dynasty = "";
String toolBarTitle = "";
if (selectedDynasty.size() > 0)
toolBarTitle += selectedDynasty.get(0) + ".";
if (selectedType.size() > 0)
toolBarTitle += selectedType.get(0) + ".";
if (selectedStyle.size() > 0)
toolBarTitle += selectedStyle.get(0);
if (selectedType.size() == 0 && selectedStyle.size() == 0)
toolBarTitle = selectedDynasty.get(0);
for (String temp : selectedType)
tag += temp + ",";
for (String temp1 : selectedStyle)
tag += temp1 + ",";
for (String temp2 : selectedDynasty)
dynasty += temp2 + ",";
intent.putExtra("from", "filter");
intent.putExtra("tag", tag);
intent.putExtra("dynasty", dynasty);
intent.putExtra("toolBarTitle", toolBarTitle);
startActivity(intent);
}
});
return root;
}
private void initView() {
sureButton = binding.sureButton;
initTagFlowLayout();
}
// 分类检索的标签初始化
private void initTagFlowLayout() {
typeTagLayout = binding.typeFloat;
dynastyTagLayout = binding.dynastyFloat;
styleTagLayout = binding.styleFloat;
typeList = PoetryUtil.getType();//获取诗词类型标签
dynastyList = PoetryUtil.getDynasty();//获取诗词朝代标签
styleList = PoetryUtil.getStyle();//获取诗词风格标签
final LayoutInflater mInflater = getLayoutInflater();
// 适配器
typeTagLayout.setAdapter(new TagAdapter<String>(typeList) {
@Override
public View getView(FlowLayout parent, int position, String s) {
TextView tv = (TextView) mInflater.inflate(R.layout.adapter_item_tag,
typeTagLayout, false);
tv.setText(s);
return tv;
}
@Override
public void onSelected(int position, View view) {
super.onSelected(position, view);
selectedType.add(typeList[position]);
showSelected(selectedType);
TextView textView = (TextView) view;
textView.setTextColor(Color.WHITE);
}
@Override
public void unSelected(int position, View view) {
super.unSelected(position, view);
TextView textView = (TextView) view;
selectedType.remove(textView.getText());
showSelected(selectedType);
textView.setTextColor(getResources().getColor(R.color.colorPrimary));
}
});
dynastyTagLayout.setAdapter(new TagAdapter<String>(dynastyList) {
@Override
public View getView(FlowLayout parent, int position, String s) {
TextView tv = (TextView) mInflater.inflate(R.layout.adapter_item_tag,
dynastyTagLayout, false);
tv.setText(s);
return tv;
}
@Override
public void onSelected(int position, View view) {
super.onSelected(position, view);
selectedDynasty.add(dynastyList[position]);
TextView textView = (TextView) view;
textView.setTextColor(Color.WHITE);
}
@Override
public void unSelected(int position, View view) {
super.unSelected(position, view);
TextView textView = (TextView) view;
selectedDynasty.remove(textView.getText());
textView.setTextColor(getResources().getColor(R.color.colorPrimary));
}
});
styleTagLayout.setAdapter(new TagAdapter<String>(styleList) {
@Override
public View getView(FlowLayout parent, int position, String s) {
TextView tv = (TextView) mInflater.inflate(R.layout.adapter_item_tag,
styleTagLayout, false);
tv.setText(s);
return tv;
}
@Override
public void onSelected(int position, View view) {
super.onSelected(position, view);
selectedStyle.add(styleList[position]);
TextView textView = (TextView) view;
textView.setTextColor(Color.WHITE);
}
@Override
public void unSelected(int position, View view) {
super.unSelected(position, view);
TextView textView = (TextView) view;
selectedStyle.remove(textView.getText());
textView.setTextColor(getResources().getColor(R.color.colorPrimary));
}
});
}
private void showSelected(List<String> temp) {
if (temp.size() > 0) {
for (String tempString : temp)
System.out.println("selectedTag:" + tempString);
} else
System.out.println("没有选择");
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

@ -0,0 +1,231 @@
package com.example.myapplication.Fragment.association;
import static com.xuexiang.xui.XUI.getContext;
import android.app.AlertDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.myapplication.Adapter.RoomAdapter;
import com.example.myapplication.Modal.RoomBean;
import com.example.myapplication.R;
import com.example.myapplication.databinding.FragmentAssociationBinding;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class AssociationFragment extends Fragment {
private FragmentAssociationBinding binding;
RecyclerView recyclerView;
List<RoomBean> roomList = new ArrayList<>();
RoomAdapter adapter;
AlertDialog.Builder createRoomBuilder ;
View createView;
ImageButton createRoomButton;
ImageButton searchButton;
AlertDialog dialog;
Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
if(message.what == 1){
System.out.println("room fresh");
//更新聊天室列表
adapter.notifyDataSetChanged();
}
return false;
}
});
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
binding = FragmentAssociationBinding.inflate(inflater, container, false);
View root = binding.getRoot();
initView();
//设置适配器
adapter = new RoomAdapter(roomList,getContext());
LinearLayoutManager manager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(manager);
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL));
recyclerView.setAdapter(adapter);
getRoomList(0,100);
//添加监听
createRoomButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
createRoomBuilder = new AlertDialog.Builder(getContext());
createView = View.inflate(getContext(),R.layout.create_room,null);
Button button = createView.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
EditText newRname = createView.findViewById(R.id.rname);
EditText newDescription = createView.findViewById(R.id.description);
String rname = String.valueOf(newRname.getText());
String description = String.valueOf(newDescription.getText());
createRoom(rname,description);
dialog.dismiss();
}
});
createRoomBuilder.setView(createView);
dialog = createRoomBuilder.create();
dialog.show();
}
});
searchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
EditText input = binding.key;
String key = String.valueOf(input.getText());
//发请求查找
OkHttpClient client = new OkHttpClient();
HttpUrl url = new HttpUrl.Builder()
.scheme("http")
.host("101.33.242.218")
.port(8081)
.addPathSegment("chatController")
.addPathSegment("getBySearch")
.addQueryParameter("key",key)
.addQueryParameter("page","0")
.addQueryParameter("size","100")
.build();
Request request = new Request.Builder()
.url(url)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
System.out.println("search failure");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
System.out.println("onResponse");
String res = response.body().string();
Gson gson = new Gson();
List<RoomBean> list = gson.fromJson(res, new TypeToken<ArrayList<RoomBean>>() {
}.getType());
roomList.clear();
roomList.addAll(list);
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}
});
}
});
return root;
}
void initView(){
recyclerView = binding.roomList;
createRoomButton = binding.createRoomButton;
searchButton = binding.searchButton;
}
void getRoomList(Integer page, Integer size){
OkHttpClient client = new OkHttpClient();
//这一部分还可调整页数刷新
HttpUrl url = new HttpUrl.Builder()
.scheme("http")
.host("101.33.242.218")
// .host("192.168.18.163")
.port(8081)
.addPathSegment("chatController")
.addPathSegment("getAllRoom")
.addQueryParameter("page", String.valueOf(page))
.addQueryParameter("size", String.valueOf(size))
.build();
Request request = new Request.Builder()
.url(url)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e("http","getAllRoom Failure");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
System.out.println("onResponse");
String res = response.body().string();
Gson gson = new Gson();
List<RoomBean> list = gson.fromJson(res, new TypeToken<ArrayList<RoomBean>>() {
}.getType());
roomList.clear();
roomList.addAll(list);
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}
});
}
void createRoom(String rname, String description){
OkHttpClient client = new OkHttpClient();
HttpUrl url = new HttpUrl.Builder()
.scheme("http")
.host("101.33.242.218")
.port(8081)
.addPathSegment("chatController")
.addPathSegment("createRoom")
.addQueryParameter("rname",rname)
.addQueryParameter("description",description)
.build();
Request request = new Request.Builder()
.url(url)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
System.out.println("create failure");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//刷新聊天室列表
//这里可以让服务器返回单个房间优化一下
getRoomList(0,100);
}
});
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

@ -0,0 +1,238 @@
package com.example.myapplication.Fragment.home;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import com.example.myapplication.Activity.DetailActivity;
import com.example.myapplication.Activity.PoetryListActivity;
import com.example.myapplication.Activity.TestActivity;
import com.example.myapplication.Api.Api;
import com.example.myapplication.Constant.constant;
import com.example.myapplication.Util.Spilt;
import com.example.myapplication.databinding.FragmentHomeBinding;
import com.scwang.smartrefresh.layout.SmartRefreshLayout;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.listener.OnRefreshListener;
import com.xuexiang.xui.widget.edittext.materialedittext.MaterialEditText;
import com.xuexiang.xui.widget.textview.label.LabelButtonView;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import okhttp3.ResponseBody;
import retrofit2.Callback;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class HomeFragment extends Fragment {
private FragmentHomeBinding binding;
private static final String TAG = "test";
// 获取诗词
private final int COMPLETED = 1;
private Retrofit SearchRetrofit;
private JSONObject poetryObject;
private SmartRefreshLayout refreshLayout;
private TextView title;
private TextView author;
private TextView content;
private TextView sentence;
private TextView tag1;
private TextView tag2;
private LabelButtonView detail;
private ImageView ic_menu;
private TextView menu_line;
private MaterialEditText searchText;
private ImageView search;
private Button testButton;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message message) {
// 获取每日诗词
if (message.what == COMPLETED) { //获取每日诗词成功
try {
title.setText(poetryObject.get("title").toString());
String dynasty_author = poetryObject.get("desty").toString() + " . "
+ poetryObject.get("author").toString();
author.setText(dynasty_author);
String contentText = poetryObject.get("content").toString();
contentText = Spilt.spiltContentText(contentText);
content.setText(contentText);
} catch (JSONException e) {
e.printStackTrace();
}
}else {
Log.e(TAG,"设置诗词失败");
}
}
};
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
binding = FragmentHomeBinding.inflate(inflater, container, false);
View root = binding.getRoot();
initView();//初始化视图
getOnePoetry();//获取每日诗词
// 设置监听
//刷新
refreshLayout.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh(RefreshLayout refreshlayout) {
getOnePoetry();
refreshLayout.finishRefresh();//结束刷新
refreshLayout.finishLoadMore(2000);//结束加载
}
});
//将数据传递给背诵页面
testButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent;
intent = new Intent(getContext(), TestActivity.class);
try {
intent.putExtra("title", poetryObject.get("title").toString());
intent.putExtra("desty", poetryObject.get("desty").toString());
intent.putExtra("author", poetryObject.get("author").toString());
intent.putExtra("content", poetryObject.get("content").toString());
} catch (JSONException e) {
e.printStackTrace();
}
startActivity(intent);
}
});
//搜索
search.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getContext(), PoetryListActivity.class);
intent.putExtra("from", "search");
intent.putExtra("toolBarTitle", searchText.getEditValue());
intent.putExtra("key", searchText.getEditValue());
startActivity(intent);
}
});
//查看详情
detail.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getContext(), DetailActivity.class);
String poemText = content.getText().toString();
String sentence = Spilt.spiltPoemTextByEnter(poemText)[0];
intent.putExtra("content", sentence);
intent.putExtra("toolbarTitle", title.getText().toString());
startActivity(intent);
}
});
return root;
}
private void initView() {
refreshLayout = binding.refreshLayout;
refreshLayout.setEnableScrollContentWhenLoaded(true);
title = binding.title;
author = binding.author;
content = binding.content;
sentence = binding.sentence;
tag1 = binding.tag1;
tag2 = binding.tag2;
testButton = binding.testButton;
ic_menu = binding.menuIcon;
menu_line = binding.menuLine;
search = binding.searchButton;
searchText = binding.search;
detail = binding.detail;
}
//随机获取一首古诗
private void getOnePoetry() {
String search_url = constant.poetry_IP;
//步骤五:构建Retrofit实例
SearchRetrofit = new Retrofit.Builder()
//设置网络请求BaseUrl地址
.baseUrl(search_url)
//设置数据解析器
.addConverterFactory(GsonConverterFactory.create())
.build();
//步骤六:创建网络请求接口对象实例
Api searchApi = SearchRetrofit.create(Api.class);
//步骤七:对发送请求进行封装,传入接口参数
retrofit2.Call<ResponseBody> searchDataCall = searchApi.getPoetry();
//步骤八:发送网络请求(同步)
Log.e(TAG, "get == url" + searchDataCall.request().url());
new Thread(new Runnable() { //Android主线程不能操作网络请求,所以new一个线程来操作
@Override
public void run() {
searchDataCall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(retrofit2.Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
try {
String responseData = response.body().string();
poetryObject = new JSONObject(responseData);
} catch (JSONException | IOException e) {
e.printStackTrace();
}
Message message = new Message();
message.what = COMPLETED;
handler.sendMessage(message);
}
@Override
public void onFailure(retrofit2.Call<ResponseBody> call, Throwable t) {
Toast.makeText(getContext(), "获取每日诗词失败", Toast.LENGTH_SHORT).show();
}
});
}
}).start();
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

@ -0,0 +1,60 @@
package com.example.myapplication.Modal;
import java.io.File;
public class ClientMessageBean {
/**
* type
* 0
* 1
* 2
* 3
* 4
*/
private int type;
private String from;
private String message;
private byte[] record;
public ClientMessageBean() {
}
public ClientMessageBean(int type, String from, String message, byte[] record) {
this.type = type;
this.from = from;
this.message = message;
this.record = record;
}
public byte[] getRecord() {
return record;
}
public void setRecord(byte[] record) {
this.record = record;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

@ -0,0 +1,36 @@
package com.example.myapplication.Modal;
/**
* @
* @ 2023/5/31 18:16
* @ ${TODO}
*/
public class Data<T> {
private int code;
private String message;
private T data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}

@ -0,0 +1,32 @@
package com.example.myapplication.Modal;
import java.util.List;
public class EmotionResBean {
private String emotion ;
private List<Double> prob;
public EmotionResBean() {
}
public EmotionResBean(String emotion, List<Double> prob) {
this.emotion = emotion;
this.prob = prob;
}
public String getEmotion() {
return emotion;
}
public void setEmotion(String emotion) {
this.emotion = emotion;
}
public List<Double> getList() {
return prob;
}
public void setList(List<Double> list) {
this.prob = list;
}
}

@ -0,0 +1,66 @@
package com.example.myapplication.Modal;
/**
* @
* @ 2023/5/31 17:58
* @ ${TODO}
*/
public class Poetry {
private String title;
private String desty;
private String author;
private String content;
private String tag;
public Poetry() {
}
public Poetry(String title, String desty, String author, String content, String tag) {
this.title = title;
this.desty = desty;
this.author = author;
this.content = content;
this.tag = tag;
}
public String getName() {
return title;
}
public void setName(String title) {
this.title = title;
}
public String getDynasty() {
return desty;
}
public void setDynasty(String desty) {
this.desty = desty;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
}

@ -0,0 +1,121 @@
package com.example.myapplication.Modal;
/**
* @
* @ 2023/5/31 17:58
* @ ${TODO}
*/
public class PoetryDetail {
private Integer id;
private String title;
private String desty;
private String author;
private String content;
private String tag;
private String trans_content;
private String zhu;
private String reference;
private String appear;
private String img;
private String authorDetail;
public PoetryDetail() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDesty() {
return desty;
}
public void setDesty(String desty) {
this.desty = desty;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public String getTransContent() {
return trans_content;
}
public void setTransContent(String trans_content) {
this.trans_content = trans_content;
}
public String getAnnotation() {
return zhu;
}
public void setAnnotation(String zhu) {
this.zhu = zhu;
}
public String getReference() {
return reference;
}
public void setReference(String reference) {
this.reference = reference;
}
public String getAppreciation() {
return appear;
}
public void setAppreciation(String appear) {
this.appear = appear;
}
public String getImg() {
return img;
}
public void setImg(String img) {
this.img = img;
}
public String getAuthorDetail() {
return authorDetail;
}
public void setAuthorDetail(String authorDetail) {
this.authorDetail = authorDetail;
}
}

@ -0,0 +1,274 @@
package com.example.myapplication.Modal;
import android.util.Log;
import com.example.myapplication.Api.Api;
import com.example.myapplication.Constant.constant;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import okhttp3.ResponseBody;
import retrofit2.Callback;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class PoetryUtil {
private static final String TAG = "test";
static Retrofit GetDynastyRetrofit;
static List<String> styles = Arrays.asList("五言", "七言");
static List<String> poem_tags = Arrays.asList("绝句", "律诗");
static HashMap<String, String> poem_type = new HashMap<String, String>();
static {
poem_type.put("绝句", "绝句");
poem_type.put("律诗", "律诗");
}
static HashMap<String, String> poemStyle = new HashMap<String, String>();
static {
poemStyle.put("五言", "五言");
poemStyle.put("七言", "七言");
}
static List<String> ci_pai = Arrays.asList("归字谣", "如梦令", "梧桐影", "渔歌子", "捣练子", "忆江南", "忆王孙", "河满子");
static String[] type =
{
"诗",
"词",
"曲",
"文言文"
};
static String[] dynasty = {
"两汉",
"五代",
"元代",
"先秦",
"南北朝",
"唐代",
"宋代",
"当代",
"明代",
"未知",
"清代",
"现代",
"近代",
"金朝",
"隋代",
"魏晋"
};
static String[] style = {
"写景",
"咏物",
"春天",
"夏天",
"秋天",
"冬天",
"写雨",
"写雪",
"写风",
"写花",
"梅花",
"荷花",
"菊花",
"柳树",
"月亮",
"山水",
"写山",
"写水",
"长江",
"黄河",
"儿童",
"写鸟",
"写马",
"田园",
"边塞",
"地名",
"抒情",
"爱国",
"离别",
"送别",
"思乡",
"思念",
"爱情",
"励志",
"哲理",
"闺怨",
"悼亡",
"写人",
"老师",
"母亲",
"友情",
"战争",
"读书",
"惜时",
"婉约",
"豪放",
"诗经",
"民谣",
"节日",
"春节",
"元宵节",
"寒食节",
"清明节",
"端午节",
"七夕节",
"中秋节",
"重阳节",
"忧国忧民",
"咏史怀古",
"宋词精选",
"小学古诗",
"初中古诗",
"高中古诗",
"小学文言文",
"初中文言文",
"高中文言文",
"古诗十九首",
"唐诗三百首",
"古诗三百首",
"宋词三百首"
};
public static List<String> getTypeList() {
List<String> typeTagList = new ArrayList<String>();
typeTagList.add("诗");
typeTagList.add("词");
typeTagList.add("曲");
typeTagList.add("文言文");
return typeTagList;
}
public static String[] getDynastyList() {
List<String> dynastyList = new ArrayList<String>();
String search_url = constant.poetry_IP;
//步骤五:构建Retrofit实例
GetDynastyRetrofit = new Retrofit.Builder()
//设置网络请求BaseUrl地址
.baseUrl(search_url)
//设置数据解析器
.addConverterFactory(GsonConverterFactory.create())
.build();
//步骤六:创建网络请求接口对象实例
Api getDynastyApi = GetDynastyRetrofit.create(Api.class);
//步骤七:对发送请求进行封装,传入接口参数
retrofit2.Call<ResponseBody> getDynastyListCall = getDynastyApi.getDynastyList();
//步骤八:发送网络请求(同步)
Log.e(TAG, "get == url" + getDynastyListCall.request().url());
Thread thread_dynasty = null;
thread_dynasty = new Thread(new Runnable() { //Android主线程不能操作网络请求,所以new一个线程来操作
@Override
public void run() {
getDynastyListCall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(retrofit2.Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
String responseData = null;
try {
responseData = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
Gson gson = new Gson();
List list = gson.fromJson(responseData, new TypeToken<List>(){}.getType());
dynastyList.addAll(list);
}
@Override
public void onFailure(retrofit2.Call<ResponseBody> call, Throwable t) {
t.printStackTrace();
}
});
}
});
thread_dynasty.start();
return dynastyList.toArray(new String[dynastyList.size()]);
}
public static List<String> getStyleList() {
List<String> styleList = new ArrayList<String>();
// HttpUtil.sendOkHttpRequest(SysConstant.YA_FENG_SERVER+"/yafeng-1.0/poetry/getAllPoemStyle", new okhttp3.Callback() {
// @Override
// public void onFailure(Call call, IOException e) {
// e.printStackTrace();
// }
//
// @Override
// public void onResponse(Call call, Response response) throws IOException {
// String responseData = response.body().string();
// try {
// resultObject = new JSONObject(responseData);
// try {
// JSONArray jsonArray;
// jsonArray = new JSONArray(resultObject.getString("data"));
// String array = jsonArray.get(0).toString();
// for (int i = 0; i < jsonArray.length(); i++) {
// styleList.add(jsonArray.get(i).toString());
// }
// } catch (JSONException e) {
// e.printStackTrace();
// }
// } catch (JSONException e) {
// e.printStackTrace();
// }
// }
// });
return styleList;
}
public static String[] getDynasty() {
return dynasty;
}
public static String[] getStyle() {
return style;
}
public static String[] getType() {
return type;
}
public static List<String> getStyles() {
return styles;
}
public static List<String> getPoemTags() {
return poem_tags;
}
public static List<String> getCiPai() {
return ci_pai;
}
public static HashMap<String, String> getPoemType() {
return poem_type;
}
public static HashMap<String, String> getPoemStyle() {
return poemStyle;
}
}

@ -0,0 +1,12 @@
package com.example.myapplication.Modal;
public class PrivateInfo {
// 自行传入appId, secretId, secretKey等参数
public static final String appId = "";
public static final String soeAppId = "";
public static final String hcmAppId = "";
public static final String secretId = "AKIDkLhOw5atyqUuthOs8xazylNo36Ugfvyn";
public static final String secretKey = "f5XpulV2MS4SdaImHclfKm26wb3A2f6K";
public static final String token = "";
}

@ -0,0 +1,40 @@
package com.example.myapplication.Modal;
public class RoomBean {
private int rid;
private String rname;
private String description;
public int getRid() {
return rid;
}
public void setRid(int rid) {
this.rid = rid;
}
public String getRname() {
return rname;
}
public void setRname(String rname) {
this.rname = rname;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public RoomBean(int rid, String rname, String description) {
this.rid = rid;
this.rname = rname;
this.description = description;
}
public RoomBean() {
}
}

@ -0,0 +1,40 @@
package com.example.myapplication.Modal;
public class SystemMessageBean {
private boolean isSystem;
private String from;
private String message;
public SystemMessageBean() {
}
public SystemMessageBean(boolean isSystem, String from, String message) {
this.isSystem = isSystem;
this.from = from;
this.message = message;
}
public boolean isSystem() {
return isSystem;
}
public void setSystem(boolean system) {
isSystem = system;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

@ -0,0 +1,67 @@
package com.example.myapplication.Util;
import java.io.*;
public class FileUtils {
/**
* Byte
*
* @return
*/
public static byte[] getBytesByFile(File file) {
try {
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
byte[] b = new byte[1024];
int n;
while ((n = fis.read(b)) != -1) {
bos.write(b, 0, n);
}
fis.close();
byte[] data = bos.toByteArray();
bos.close();
return data;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Byte
*
* @param bytes
* @param filePath
* @param fileName
*/
public static void getFileByBytes(byte[] bytes, String filePath, String fileName) {
BufferedOutputStream bos = null;
FileOutputStream fos = null;
File file = null;
try {
file = new File(filePath + fileName);
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(bytes);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

@ -0,0 +1,29 @@
package com.example.myapplication.Util;
public class Spilt {
public Spilt() {
}
public static String spiltContentText(String contentText) {
String result = "";
String split[];
String regex = "\\(.*\\)";
contentText = contentText.replaceAll(regex,"");
split = contentText.split("。");
for(int i = 0; i < split.length; i++){
result = result + split[i] + "。" + "\n";
}
return result;
}
//按换行分割字符串
public static String[] spiltPoemTextByEnter(String poemText) {
String result[];
result = poemText.split("\n");
return result;
}
}

@ -0,0 +1,110 @@
package com.example.myapplication.Util;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.NonNull;
import com.example.myapplication.Modal.ClientMessageBean;
import com.example.myapplication.Modal.SystemMessageBean;
import com.google.gson.Gson;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.logging.LogRecord;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;
public class WebSocketUtil {
private static final int NORMAL_CLOSURE_STATUS = 1000;
private final OkHttpClient client = new OkHttpClient.Builder()
.pingInterval(10, TimeUnit.SECONDS)
.build();
private WebSocket socket;
private WebSocketListener listener;
private Map<String, WebSocket> webSockets = new ConcurrentHashMap<>();
private Handler handler;
public void connect(String url, Integer rid,String username, Handler handler) {
this.handler = handler;
url = url + rid+"/"+username;
Request request = new Request.Builder()
.url(url)
.build();
listener = new WebSocketListener() {
@Override
public void onOpen(WebSocket webSocket, Response response) {
System.out.println("open");
socket = webSocket;
}
@Override
public void onMessage(WebSocket webSocket, String text) {
// 接收到服务端发来的消息
Log.d("WebSocket", "onMessage: " + text);
Message message = new Message();
Gson gson = new Gson();
SystemMessageBean messageBean = gson.fromJson(text,SystemMessageBean.class);
message.obj = messageBean;
handler.sendMessage(message);
}
@Override
public void onMessage(WebSocket webSocket, ByteString bytes) {
// 接收到服务端发来的消息
Log.d("WebSocket", "onMessage: " + bytes.toString());
}
@Override
public void onClosing(WebSocket webSocket, int code, String reason) {
webSocket.close(NORMAL_CLOSURE_STATUS, null);
}
@Override
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
Log.e("WebSocket", "onFailure", t);
}
};
socket = client.newWebSocket(request, listener);
System.out.println("connect");
}
public void send(String message) {
// 在房间内发送消息
socket.send(message);
}
public void send(ByteString message) {
// 在房间内发送消息
socket.send(message);
}
public void disconnect() {
if (socket != null) {
socket.close(NORMAL_CLOSURE_STATUS, null);
}
client.dispatcher().executorService().shutdown();
}
public void addWebSocket(String clientId, WebSocket webSocket) {
webSockets.put(clientId, webSocket);
}
public void removeWebSocket(String clientId) {
webSockets.remove(clientId);
}
}

@ -0,0 +1,16 @@
package com.example.myapplication;
import android.app.Application;
import com.example.myapplication.Fragment.AiPoetry.AiPoetryFragment;
import com.xuexiang.xui.XUI;
public class XUIInit extends Application {
@Override
public void onCreate() {
super.onCreate();
XUI.init(this);
XUI.debug(true);
}
}

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
~
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="?attr/colorAccent" />
<item android:state_selected="true" android:color="?attr/colorAccent" />
<item android:state_enabled="false" android:color="@color/xui_btn_disable_color" />
<item android:color="?attr/colorAccent" />
</selector>

@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="@color/xui_config_color_light_blue"/>
<corners android:radius="?attr/xui_btn_view_radius"/>
</shape>
</item>
<item
android:state_checked="true">
<shape android:shape="rectangle">
<solid android:color="@color/xui_config_color_light_blue"/>
<corners android:radius="?attr/xui_btn_view_radius"/>
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="@color/xui_config_color_white"/>
<corners android:radius="?attr/xui_btn_view_radius"/>
<stroke android:width="1dp" android:color="@color/xui_config_color_light_blue"/>
</shape>
</item>
</selector>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 这里是设置背景色-->
<solid android:color="#FFFFFF" />
<!-- 这里是设置为四周 也可以单独设置某个位置为圆角-->
<corners android:topLeftRadius="5dp"
android:topRightRadius="5dp"
android:bottomRightRadius="5dp"
android:bottomLeftRadius="5dp"/>
<!-- 这里设置边框 -->
<stroke android:width="1dp" android:color="#DADADA" />
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

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

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:padding="10dp"
android:shape="rectangle">
<solid android:color="#fff"/>
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp"/>
<stroke android:color="@color/xui_config_color_titlebar"
android:width="2px"
/>
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 B

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M3,13h8L11,3L3,3v10zM3,21h8v-6L3,15v6zM13,21h8L21,11h-8v10zM13,3v6h8L21,3h-8z" />
</vector>

@ -0,0 +1,26 @@
<!--
~ Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
~
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#707070"
android:pathData="M512,0c281.6,0 512,230.4 512,512s-230.4,512 -512,512 -512,-230.4 -512,-512 230.4,-512 512,-512zM627.2,505.6c44.8,-38.4 76.8,-89.6 76.8,-153.6 0,-108.8 -83.2,-192 -192,-192s-192,83.2 -192,192c0,64 32,115.2 76.8,153.6 -102.4,44.8 -172.8,147.2 -172.8,262.4 0,19.2 12.8,32 32,32s32,-12.8 32,-32c0,-121.6 102.4,-224 224,-224s224,102.4 224,224c0,19.2 12.8,32 32,32s32,-12.8 32,-32c0,-115.2 -70.4,-217.6 -172.8,-262.4zM512,480c-70.4,0 -128,-57.6 -128,-128s57.6,-128 128,-128 128,57.6 128,128 -57.6,128 -128,128z" />
</vector>

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z" />
</vector>

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 B

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z" />
</vector>

@ -0,0 +1,18 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M869.03,393.85a54.14,54.14 0,0 1,54.14 54.14v467.74a54.14,54.14 0,0 1,-54.14 54.14H154.97a54.14,54.14 0,0 1,-54.14 -54.14V447.98a54.14,54.14 0,0 1,54.14 -54.14h714.07m0,-54.14H154.97a108.27,108.27 0,0 0,-108.27 108.27v467.74a108.27,108.27 0,0 0,108.27 108.27h714.07a108.27,108.27 0,0 0,108.27 -108.27V447.98a108.27,108.27 0,0 0,-108.27 -108.27z"
android:fillColor="#000000"/>
<path
android:pathData="M817.87,362.72h-54.14v-56.84a251.74,251.74 0,1 0,-503.47 0v56.84h-54.14v-56.84a305.87,305.87 0,1 1,611.75 0z"
android:fillColor="#000000"/>
<path
android:pathData="M438.64,520.53m71.46,0l3.79,0q71.46,0 71.46,71.46l0,3.79q0,71.46 -71.46,71.46l-3.79,0q-71.46,0 -71.46,-71.46l0,-3.79q0,-71.46 71.46,-71.46Z"
android:fillColor="#000000"/>
<path
android:pathData="M483.04,567.63m28.15,0l1.35,0q28.15,0 28.15,28.15l0,204.37q0,28.15 -28.15,28.15l-1.35,0q-28.15,0 -28.15,-28.15l0,-204.37q0,-28.15 28.15,-28.15Z"
android:fillColor="#000000"/>
</vector>

@ -0,0 +1,4 @@
<vector android:height="24dp" android:viewportHeight="1024"
android:viewportWidth="1024" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#000000" android:pathData="M640,542.72c76.8,-44.8 128,-128 128,-217.6 0,-140.8 -115.2,-256 -256,-256s-256,108.8 -256,249.6c0,96 51.2,172.8 128,217.6 -166.4,51.2 -281.6,204.8 -288,384 0,25.6 12.8,38.4 32,38.4s32,-12.8 32,-32c6.4,-192 160,-345.6 352,-345.6s345.6,153.6 352,345.6c0,19.2 12.8,32 32,32s32,-12.8 32,-32c-6.4,-179.2 -121.6,-332.8 -288,-384zM320,318.72c0,-108.8 83.2,-192 192,-192s192,83.2 192,192 -83.2,192 -192,192 -192,-83.2 -192,-192z"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 797 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 616 B

@ -0,0 +1,29 @@
<!--
~ Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
~
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#8a8a8a"
android:pathData="M595.71,526.11l-205.44,-197.28c-8.86,-10.43 -7.5,-25.97 3.02,-34.69 10.53,-8.74 26.24,-7.36 35.09,3.07l205.42,197.28c8.86,10.43 7.5,25.97 -3.01,34.69S604.56,536.56 595.71,526.11z" />
<path
android:fillColor="#8a8a8a"
android:pathData="M390.26,695.68l205.44,-197.28c8.86,-10.43 24.56,-11.81 35.09,-3.09 10.53,8.74 11.87,24.27 3.02,34.69l-205.44,197.28c-8.85,10.43 -24.56,11.81 -35.09,3.07C382.75,721.66 381.39,706.13 390.26,695.68z" />
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 573 B

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:padding="10dp"
android:shape="rectangle">
<solid android:color="#fff"/>
<corners
android:bottomLeftRadius="30dp"
android:bottomRightRadius="30dp"
android:topLeftRadius="30dp"
android:topRightRadius="30dp"/>
<stroke android:color="@color/xui_config_color_titlebar"
android:width="2px"
/>
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Activity.AdviceActivity"
android:orientation="vertical">
<TextView
android:id="@+id/poetryTitle"
android:layout_width="match_parent"
android:layout_height="50dp"
tools:ignore="MissingConstraints"
android:gravity="center"/>
<com.xuexiang.xui.widget.edittext.MultiLineEditText
android:id="@+id/advice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
app:mlet_maxCount="500"
tools:ignore="MissingConstraints" />
<com.xuexiang.xui.widget.button.ButtonView
android:id="@+id/advice_btn"
style="@style/ButtonView.Blue"
android:layout_marginTop="20dp"
android:layout_gravity="center_horizontal"
android:text="@string/advice" />
</LinearLayout>

@ -0,0 +1,384 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Activity.DetailActivity">
<!--标题栏-->
<androidx.appcompat.widget.Toolbar
android:id="@+id/poem_titleBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/xui_config_color_titlebar"
android:textAlignment="center"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/poem_titleText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="title"
android:textColor="#fff"
android:textSize="20dp"
android:textStyle="bold"/>
<ImageView
android:id="@+id/poem_menu_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="right"
android:layout_marginRight="10dp"
android:src="@drawable/icon_collect1"/>
<ImageView
android:id="@+id/poem_menu_advice"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="right"
android:layout_marginRight="10dp"
android:src="@drawable/advice"/>
</androidx.appcompat.widget.Toolbar>
<TextView
android:id="@+id/menu_line"
android:layout_width="1dp"
android:layout_height="1dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/poem_titleBar"/>
<ScrollView
android:id="@+id/detail_scroll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:paddingBottom="20dp"
app:layout_constraintTop_toBottomOf="@id/menu_line">
<LinearLayout
android:id="@+id/poem_linnear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fff"
android:orientation="vertical">
<!--诗词正文-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/detail_poem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fff"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<!-- 诗词内容-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/poem_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="30dp"
android:paddingTop="30dp"
android:paddingRight="30dp"
android:paddingBottom="10dp"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/detail_poem_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="title"
android:textAlignment="center"
android:textSize="16dp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/detail_poem_author"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="dynasty . author"
android:textAlignment="center"
android:textSize="16dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/detail_poem_title"/>
<TextView
android:id="@+id/detail_poem_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="5dp"
android:lineSpacingMultiplier="1.3"
android:text="content"
android:textAlignment="center"
android:textSize="16dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/detail_poem_author"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- 标签-->
<!-- <com.zhy.view.flowlayout.TagFlowLayout-->
<!-- android:id="@+id/tag_flow"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginLeft="60dp"-->
<!-- android:foregroundGravity="center"-->
<!-- app:layout_constraintLeft_toLeftOf="parent"-->
<!-- app:layout_constraintRight_toRightOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@id/poem_panel"-->
<!-- zhy:max_select="1"></com.zhy.view.flowlayout.TagFlowLayout>-->
<TextView
android:id="@+id/tag_flow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="60dp"
android:foregroundGravity="center"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/poem_panel"
/>
<!-- 背诵-->
<com.xuexiang.xui.widget.button.roundbutton.RoundButton
android:id="@+id/poem_test_button"
style="@style/RoundButton.Auto"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_marginTop="30dp"
android:text="测试一下"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tag_flow"
app:layout_constraintWidth_percent="0.6"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<!--作者详情-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/author_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="30dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tag_flow">
<com.xuexiang.xui.widget.imageview.RadiusImageView
android:id="@+id/author_img"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:riv_border_color="@color/xui_config_color_gray_6"
app:riv_border_width="1px"
app:riv_is_circle="true"/>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/author_border"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="-10dp"
android:background="@drawable/round_editstyle"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/author_img">
<TextView
android:id="@+id/author_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lineSpacingMultiplier="1.3"
android:padding="10dp"
android:text="authorDetail"
android:textAlignment="center"
android:textSize="16dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<!--赏析、注释等信息-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/author_panel">
<!--翻译-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/translation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/detail_label1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/type_label"
android:layout_width="5dp"
android:layout_height="20dp"
android:layout_marginLeft="20dp"
android:background="@drawable/type_label_style"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="7dp"
android:text="诗词释义"
app:layout_constraintLeft_toRightOf="@id/type_label"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/translation_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lineSpacingMultiplier="1.3"
android:padding="30dp"
android:text="暂无翻译"
android:textAlignment="center"
android:textSize="16dp"
app:layout_constraintTop_toBottomOf="@id/detail_label1"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<!--赏析-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/appreciation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/translation">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/detail_label2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/type_label2"
android:layout_width="5dp"
android:layout_height="20dp"
android:layout_marginLeft="20dp"
android:background="@drawable/label_style"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="7dp"
android:text="诗词赏析"
app:layout_constraintLeft_toRightOf="@id/type_label2"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/appreciation_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lineSpacingMultiplier="1.3"
android:padding="30dp"
android:text="暂无赏析"
android:textAlignment="center"
android:textSize="16dp"
app:layout_constraintTop_toBottomOf="@id/detail_label2"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<!--注释-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/annotation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/appreciation">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/detail_label3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/type_label3"
android:layout_width="5dp"
android:layout_height="20dp"
android:layout_marginLeft="20dp"
android:background="@drawable/dynasty_label_style"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="7dp"
android:text="诗词注释"
app:layout_constraintLeft_toRightOf="@id/type_label3"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<org.sufficientlysecure.htmltextview.HtmlTextView
android:id="@+id/annotation_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lineSpacingMultiplier="1.3"
android:padding="30dp"
android:text="暂无注释"
android:textAlignment="center"
android:textSize="16dp"
app:layout_constraintTop_toBottomOf="@id/detail_label3"/>
<Space
android:layout_width="match_parent"
android:layout_height="20dp"
app:layout_constraintTop_toBottomOf="@id/annotation_text"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,193 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:orientation="vertical">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_gravity="center_horizontal"
app:srcCompat="@drawable/app"
android:layout_marginTop="40dp"/>
<TextView
style="@style/TextStyle.Title"
android:layout_width="match_parent"
android:layout_marginTop="10dp"
android:text="登 录"
android:textSize="30sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:tint="?attr/colorAccent"
app:srcCompat="@drawable/ic_phone" />
<com.xuexiang.xui.widget.edittext.materialedittext.MaterialEditText
android:id="@+id/et_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="36dp"
android:hint="@string/tip_please_input_username"
app:met_clearButton="true"
app:met_errorMessage="@string/tip_phone_number_error"
app:met_floatingLabel="normal"
app:met_floatingLabelText="@string/title_username" />
</FrameLayout>
<FrameLayout
android:id="@+id/fl_verify_code"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:tint="?attr/colorAccent"
app:srcCompat="@drawable/ic_password" />
<com.xuexiang.xui.widget.edittext.materialedittext.MaterialEditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="36dp"
android:hint="@string/hint_please_input_verify_code"
app:met_clearButton="false"
app:met_errorMessage="@string/tip_error"
app:met_floatingLabel="normal"
app:met_floatingLabelText="@string/title_password"
app:met_maxCharacters="11" />
<!-- <com.xuexiang.xui.widget.button.roundbutton.RoundButton-->
<!-- android:id="@+id/btn_get_verify_code"-->
<!-- style="@style/RoundButton"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_gravity="end"-->
<!-- android:paddingStart="10dp"-->
<!-- android:paddingTop="3dp"-->
<!-- android:paddingEnd="10dp"-->
<!-- android:paddingBottom="3dp"-->
<!-- android:text="@string/action_get_verify_code"-->
<!-- android:textColor="@color/selector_round_button_main_theme_color"-->
<!-- android:textSize="13sp"-->
<!-- app:rb_borderColor="@color/selector_round_button_main_theme_color"-->
<!-- app:rb_borderWidth="1.5dp"-->
<!-- app:rb_radius="15dp" />-->
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.xuexiang.xui.widget.alpha.XUIAlphaTextView
android:id="@+id/tv_other_login"
style="@style/TextStyle.Explain"
android:layout_gravity="start"
android:paddingStart="10dp"
android:paddingTop="5dp"
android:paddingEnd="10dp"
android:paddingBottom="5dp"
android:text="其他登录方式"
android:textColor="@color/xui_config_color_primary_text" />
<com.xuexiang.xui.widget.alpha.XUIAlphaTextView
android:id="@+id/tv_forget_password"
style="@style/TextStyle.Explain"
android:layout_gravity="end"
android:paddingStart="10dp"
android:paddingTop="5dp"
android:paddingEnd="10dp"
android:paddingBottom="5dp"
android:text="忘记密码"
android:textColor="@color/xui_config_color_primary_text" />
</FrameLayout>
</LinearLayout>
<com.xuexiang.xui.widget.textview.supertextview.SuperButton
android:id="@+id/bt_login"
style="@style/SuperButton.Primary.Login"
android:layout_marginTop="16dp"
android:text="@string/title_login" />
<com.xuexiang.xui.widget.textview.supertextview.SuperButton
android:id="@+id/bt_register"
style="@style/SuperButton.Primary.Login"
android:layout_marginTop="16dp"
android:text="@string/title_register" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginBottom="20dp"
android:gravity="center"
android:orientation="horizontal">
<CheckBox
android:id="@+id/cb_protocol"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleX="0.7"
android:scaleY="0.7" />
<TextView
style="@style/TextStyle.Explain"
android:layout_width="wrap_content"
android:text="@string/agree_protocol"
android:textColor="@color/xui_config_color_primary_text" />
<com.xuexiang.xui.widget.alpha.XUIAlphaTextView
android:id="@+id/tv_user_protocol"
style="@style/TextStyle.Explain"
android:layout_width="wrap_content"
android:text="@string/title_user_protocol"
android:textColor="?attr/colorAccent" />
<TextView
style="@style/TextStyle.Explain"
android:layout_width="wrap_content"
android:text="@string/lab_and"
android:textColor="@color/xui_config_color_primary_text" />
<com.xuexiang.xui.widget.alpha.XUIAlphaTextView
android:id="@+id/tv_privacy_protocol"
style="@style/TextStyle.Explain"
android:layout_width="wrap_content"
android:text="@string/title_privacy_protocol"
android:textColor="?attr/colorAccent" />
</LinearLayout>
</FrameLayout>
</LinearLayout>

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--主页面-->
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/bottom_nav_menu" />
<androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/nav_view" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- 侧边栏-->
<com.google.android.material.navigation.NavigationView
android:id="@+id/search"
android:layout_width="350dp"
android:layout_height="match_parent"
android:layout_gravity="start"
tools:ignore="MissingConstraints" >
<FrameLayout
android:id="@+id/fragment_search"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</com.google.android.material.navigation.NavigationView>
</androidx.drawerlayout.widget.DrawerLayout>

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Activity.PoetryListActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/titleBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/xui_config_color_titlebar"
android:textAlignment="center"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/titleText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="title"
android:textColor="#fff"
android:textSize="20dp"/>
</androidx.appcompat.widget.Toolbar>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<com.scwang.smartrefresh.layout.SmartRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/refreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toBottomOf="@id/titleBar">
<ListView
android:id="@+id/poemList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff"
app:layout_constraintTop_toTopOf="parent"/>
</com.scwang.smartrefresh.layout.SmartRefreshLayout>
</LinearLayout>
</LinearLayout>

@ -0,0 +1,142 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:orientation="vertical">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_gravity="center_horizontal"
app:srcCompat="@drawable/app"
android:layout_marginTop="40dp"/>
<TextView
style="@style/TextStyle.Title"
android:layout_width="match_parent"
android:layout_marginTop="10dp"
android:text="注 册"
android:textSize="30sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:tint="?attr/colorAccent"
app:srcCompat="@drawable/ic_phone" />
<com.xuexiang.xui.widget.edittext.materialedittext.MaterialEditText
android:id="@+id/r_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="36dp"
android:hint="@string/tip_please_input_username"
app:met_clearButton="true"
app:met_errorMessage="@string/tip_phone_number_error"
app:met_floatingLabel="normal"
app:met_floatingLabelText="@string/title_username" />
</FrameLayout>
<FrameLayout
android:id="@+id/fl_verify_code"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:tint="?attr/colorAccent"
app:srcCompat="@drawable/ic_password" />
<com.xuexiang.xui.widget.edittext.materialedittext.MaterialEditText
android:id="@+id/r_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="36dp"
android:hint="@string/hint_please_input_verify_code"
app:met_clearButton="false"
app:met_errorMessage="@string/tip_error"
app:met_floatingLabel="normal"
app:met_floatingLabelText="@string/title_password"
app:met_maxCharacters="11" />
</FrameLayout>
</LinearLayout>
<com.xuexiang.xui.widget.textview.supertextview.SuperButton
android:id="@+id/bt_register"
style="@style/SuperButton.Primary.Login"
android:layout_marginTop="16dp"
android:text="@string/title_register" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginBottom="20dp"
android:gravity="center"
android:orientation="horizontal">
<CheckBox
android:id="@+id/cb_protocol"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleX="0.7"
android:scaleY="0.7" />
<TextView
style="@style/TextStyle.Explain"
android:layout_width="wrap_content"
android:text="@string/agree_protocol"
android:textColor="@color/xui_config_color_primary_text" />
<com.xuexiang.xui.widget.alpha.XUIAlphaTextView
android:id="@+id/tv_user_protocol"
style="@style/TextStyle.Explain"
android:layout_width="wrap_content"
android:text="@string/title_user_protocol"
android:textColor="?attr/colorAccent" />
<TextView
style="@style/TextStyle.Explain"
android:layout_width="wrap_content"
android:text="@string/lab_and"
android:textColor="@color/xui_config_color_primary_text" />
<com.xuexiang.xui.widget.alpha.XUIAlphaTextView
android:id="@+id/tv_privacy_protocol"
style="@style/TextStyle.Explain"
android:layout_width="wrap_content"
android:text="@string/title_privacy_protocol"
android:textColor="?attr/colorAccent" />
</LinearLayout>
</FrameLayout>
</LinearLayout>

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Activity.TestActivity">
<!-- 具体诗词原文-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/poetpanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<!-- 诗词名-->
<TextView
android:id="@+id/title"
android:layout_width="408dp"
android:layout_height="32dp"
android:layout_marginTop="20dp"
android:text="title"
android:textAlignment="center"
android:textSize="16dp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- 作者朝代-->
<TextView
android:id="@+id/author"
android:layout_width="403dp"
android:layout_height="44dp"
android:layout_marginTop="5dp"
android:text="dynasty . author"
android:textAlignment="center"
android:textSize="16dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/title" />
<!-- 原文-->
<ScrollView
android:layout_width="307dp"
android:layout_height="153dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/author"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
tools:ignore="MissingConstraints" />
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
<Button
android:id="@+id/startRecord"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="onRecord"
android:text="开始测试" />
<Space
android:layout_width="match_parent"
android:layout_height="15dp" />
<Button
android:id="@+id/viewAns"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查看答案" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.mikephil.charting.charts.HorizontalBarChart
android:id="@+id/ratings"
android:layout_width="360dp"
android:layout_height="207dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.49"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</com.github.mikephil.charting.charts.HorizontalBarChart>
<TextView
android:id="@+id/result"
android:layout_width="261dp"
android:layout_height="64dp"
android:text=""
android:textSize="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/ratings" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:id="@+id/tv_tag"
style="@style/TextStyle.Explain"
android:layout_height="32dp"
android:layout_marginLeft="?attr/xui_config_content_spacing_horizontal"
android:layout_marginTop="?attr/xui_config_content_spacing_horizontal"
android:background="@drawable/bg_rect_round_blue"
android:paddingBottom="5dp"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="5dp"
android:textColor="@color/xui_config_color_titlebar"
xmlns:android="http://schemas.android.com/apk/res/android"/>

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/text_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageButton
android:id="@+id/change_to_voice"
android:layout_width="40dp"
android:layout_height="50dp"
android:layout_weight="1"
android:scaleType="fitXY"
app:srcCompat="@drawable/voice" />
<EditText
android:id="@+id/input_txet"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="15"
android:hint="请输入内容"
android:maxLines="2"
/>
<Button
android:id="@+id/send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#1EBD3D"
android:text="发送"
android:textColor="#fff" />
</LinearLayout>
<LinearLayout
android:id="@+id/voice_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageButton
android:id="@+id/back_to_text"
android:layout_width="40dp"
android:layout_height="50dp"
android:layout_weight="1"
android:scaleType="fitXY"
app:srcCompat="@drawable/voice" />
<Button
android:id="@+id/record_voice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="15"
android:text="按住说话"
android:layout_marginTop="10dp"/>
</LinearLayout>
</LinearLayout>

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/msg_recycle_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<include layout="@layout/bottom"/>
</LinearLayout>

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/head"
android:layout_width="178dp"
android:layout_height="46dp"
android:layout_marginTop="16dp"
android:text="创建聊天室"
android:textAlignment="center"
android:textSize="30dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="298dp"
android:layout_height="196dp"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/head"
android:layout_marginTop="20dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="聊天室名"
android:textSize="15dp" />
<EditText
android:id="@+id/rname"
android:layout_width="223dp"
android:layout_height="wrap_content" />
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="65dp"
android:layout_weight="1"
android:text="简介"
android:textSize="20dp" />
<EditText
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="110dp" />
</LinearLayout>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="确认"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linearLayout" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,182 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:zhy="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragment.AiPoetry.AiPoetryFragment">
<!-- 顶部导航-->
<androidx.appcompat.widget.Toolbar
android:id="@+id/titleBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/xui_config_color_titlebar"
android:textAlignment="center"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="AI 诗 人"
android:textColor="#fff"
android:textSize="20dp"
android:textStyle="bold"/>
<ImageView
android:id="@+id/menu_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="right"
android:layout_marginRight="10dp"
android:src="@drawable/ic_setting"/>
</androidx.appcompat.widget.Toolbar>
<TextView
android:id="@+id/menu_line"
android:layout_width="1dp"
android:layout_height="1dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/titleBar"/>
<!--诗词体裁选择-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/ai_tag_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/menu_line"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginTop="150dp">
<com.zhy.view.flowlayout.TagFlowLayout
android:id="@+id/ai_poem_tag_flow"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:foregroundGravity="center"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintWidth_percent="0.6"
app:layout_constraintTop_toTopOf="@id/ai_tag_layout"
zhy:max_select="1">
</com.zhy.view.flowlayout.TagFlowLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/ai_spilt_line"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/ai_poem_tag_flow"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginTop="15dp">
<com.zhy.view.flowlayout.TagFlowLayout
android:id="@+id/ai_style_tag_flow"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:foregroundGravity="center"
app:layout_constraintWidth_percent="0.5"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/ai_spilt_line"
zhy:max_select="1">
</com.zhy.view.flowlayout.TagFlowLayout>
<!--<com.xuexiang.xui.widget.spinner.materialspinner.MaterialSpinner
style="@style/Material.SpinnerStyle"
android:id="@+id/ai_ci_pai"
android:layout_width="wrap_content"
android:layout_height="32dp"
android:visibility="invisible"
app:layout_constraintLeft_toRightOf="@id/ai_style_tag_flow"
app:layout_constraintTop_toTopOf="@id/ai_spilt_line"/>
-->
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<!--诗词创作-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/ai_creating_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingTop="25dp"
app:layout_constraintTop_toBottomOf="@id/ai_tag_layout"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<!--输入框-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/create_bar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/ai_creating_layout">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/ai_input_bar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/editstyle"
app:layout_constraintHorizontal_bias="0.297"
app:layout_constraintWidth_percent="0.5"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.xuexiang.xui.widget.edittext.materialedittext.MaterialEditText
android:id="@+id/input_keyword"
style="@style/EditText.Normal"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginLeft="1dp"
android:hint="输入关键词组"
android:textAlignment="center"
android:textColorHint="@color/xui_config_color_titlebar"
android:textSize="15dp"
app:layout_constraintHorizontal_bias="0.297"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:met_autoValidate="true"
app:met_errorMessage="请输入中文字符"
app:met_hideUnderline="true"
app:met_regexp="[\u4e00-\u9fa5|\s]+"
app:met_underlineColor="#fff"
app:met_validateOnFocusLost="true"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<com.xuexiang.xui.widget.button.roundbutton.RoundButton
android:id="@+id/creating_button"
style="@style/RoundButton.Auto"
android:layout_width="0dp"
android:layout_height="40dp"
android:text="开始"
android:textColor="#fff"
app:rb_backgroundColor="@color/xui_config_color_titlebar"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toRightOf="@id/ai_input_bar"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.2"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/created_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="30dp"
android:layout_marginRight="5dp"
android:lineSpacingMultiplier="1.3"
android:textAlignment="center"
android:textSize="16dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/create_bar"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Fragment.association.AssociationFragment"
android:focusable="true"
android:focusableInTouchMode="true">
<!-- 顶部导航-->
<androidx.appcompat.widget.Toolbar
android:id="@+id/titleBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/xui_config_color_titlebar"
android:textAlignment="center"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="社 群"
android:textColor="#fff"
android:textSize="20dp"
android:textStyle="bold"/>
<ImageView
android:id="@+id/menu_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="right"
android:layout_marginRight="10dp"
android:src="@drawable/ic_setting"/>
</androidx.appcompat.widget.Toolbar>
<TextView
android:id="@+id/menu_line"
android:layout_width="1dp"
android:layout_height="1dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/titleBar"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/key"
android:layout_width="200dp"
android:layout_height="match_parent"
android:layout_weight="4"
/>
<ImageButton
android:id="@+id/searchButton"
android:layout_width="14dp"
android:layout_height="44dp"
android:layout_weight="1"
app:srcCompat="@drawable/search"
android:scaleType="fitXY"
android:background="@android:color/transparent"
/>
<ImageButton
android:id="@+id/createRoomButton"
android:layout_width="14dp"
android:layout_height="44dp"
android:layout_weight="1"
android:background="@android:color/transparent"
android:scaleType="fitXY"
app:srcCompat="@drawable/create_room" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/room_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</androidx.recyclerview.widget.RecyclerView>
<Space
android:layout_width="match_parent"
android:layout_height="50dp" />
</LinearLayout>

@ -0,0 +1,301 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragment.home.HomeFragment">
<!-- 顶部导航-->
<androidx.appcompat.widget.Toolbar
android:id="@+id/titleBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/xui_config_color_titlebar"
android:textAlignment="center"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="每 日 推 荐"
android:textColor="#fff"
android:textSize="20dp"
android:textStyle="bold"/>
<ImageView
android:id="@+id/menu_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="right"
android:layout_marginRight="10dp"
android:src="@drawable/ic_setting"/>
</androidx.appcompat.widget.Toolbar>
<TextView
android:id="@+id/menu_line"
android:layout_width="1dp"
android:layout_height="1dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/titleBar"/>
<!-- 主页面-->
<ScrollView
android:id="@+id/detail_scroll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:paddingBottom="20dp"
app:layout_constraintTop_toBottomOf="@id/menu_line">
<com.scwang.smartrefresh.layout.SmartRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/refreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toBottomOf="@id/titleBar">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/titleBar">
<!--每日一句-->
<TextView
android:id="@+id/label1"
android:layout_width="5dp"
android:layout_height="20dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="60dp"
android:background="@drawable/type_label_style"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginTop="60dp"
android:text="每日一句"
app:layout_constraintLeft_toRightOf="@id/label1"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/dailySentence"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/sentence"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="荷花开后西湖好,载酒来时。"
android:textSize="20dp"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="@id/dailySentence"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/sentence">
<TextView
android:id="@+id/tag1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="华东"
android:textSize="15dp"/>
<TextView
android:id="@+id/tag2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="西湖"
android:textSize="15dp"/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<!--搜索框-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/search_bar"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:background="@drawable/round_editstyle"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/dailySentence">
<com.xuexiang.xui.widget.edittext.materialedittext.MaterialEditText
android:id="@+id/search"
style="@style/EditText.Normal"
android:layout_width="0dp"
android:layout_height="40dp"
android:hint="输入诗名或作者或诗句进行查询"
android:textAlignment="center"
android:textColorHint="@color/xui_config_color_titlebar"
android:textSize="15dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.8"
app:met_autoValidate="true"
app:met_errorMessage="请输入中文字符"
app:met_hideUnderline="true"
app:met_iconPadding="8dp"
app:met_regexp="[\u4e00-\u9fa5|\s]+"
app:met_underlineColor="#fff"
app:met_validateOnFocusLost="true"/>
<ImageView
android:id="@+id/search_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginRight="0dp"
android:src="@drawable/ic_search"
app:layout_constraintLeft_toRightOf="@id/search"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<!--每日一诗-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/poet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/search_bar">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/labelbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/label"
android:layout_width="5dp"
android:layout_height="20dp"
android:layout_marginLeft="20dp"
android:background="@drawable/label_style"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="7dp"
android:text="每日一诗"
app:layout_constraintLeft_toRightOf="@id/label"
app:layout_constraintTop_toTopOf="parent"/>
<com.xuexiang.xui.widget.textview.label.LabelButtonView
android:id="@+id/detail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:text="查看详情"
android:textColor="@color/xui_config_color_titlebar"
android:textSize="15dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- 具体诗词原文-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/poetpanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/labelbar">
<!-- 诗词名-->
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="title"
android:textAlignment="center"
android:textSize="16dp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<!-- 作者朝代-->
<TextView
android:id="@+id/author"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="dynasty . author"
android:textAlignment="center"
android:textSize="16dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/title"/>
<!-- 原文-->
<TextView
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:lineSpacingMultiplier="1.3"
android:text="content"
android:textAlignment="center"
android:singleLine="false"
android:textSize="16dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/author"/>
<!-- 背诵朗诵功能-->
<com.xuexiang.xui.widget.button.roundbutton.RoundButton
android:id="@+id/test_button"
style="@style/RoundButton.Auto"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_marginTop="30dp"
android:text="测试一下"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/content"
app:layout_constraintWidth_percent="0.6"/>
<Space
android:layout_width="wrap_content"
android:layout_height="50dp"
app:layout_constraintTop_toBottomOf="@id/test_button"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.scwang.smartrefresh.layout.SmartRefreshLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/myActivity"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragment.My.MyFragment">
<!-- 顶部导航-->
<androidx.appcompat.widget.Toolbar
android:id="@+id/titleBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/xui_config_color_titlebar"
android:textAlignment="center"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="-16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="我 的"
android:textColor="#fff"
android:textSize="20dp"
android:textStyle="bold" />
<ImageView
android:id="@+id/menu_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="right"
android:layout_marginRight="10dp"
android:src="@drawable/ic_setting" />
</androidx.appcompat.widget.Toolbar>
<TextView
android:id="@+id/menu_line"
android:layout_width="1dp"
android:layout_height="1dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/titleBar"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="40dp"
android:orientation="vertical"
android:paddingTop="20dp"
app:layout_constraintTop_toBottomOf="@+id/titleBar"
>
<com.xuexiang.xui.widget.textview.supertextview.SuperTextView
style="@style/InfoItem.Account"
android:layout_height="60dp"
app:sLeftTextString="头像">
<com.xuexiang.xui.widget.imageview.RadiusImageView
android:id="@+id/riv_head_pic"
style="@style/RadiusImageView.Circle"
android:layout_width="38dp"
android:layout_height="38dp"
android:layout_centerVertical="true"
android:layout_toStartOf="@id/sRightImgId"
app:srcCompat="@drawable/ic_default_head" />
</com.xuexiang.xui.widget.textview.supertextview.SuperTextView>
<com.xuexiang.xui.widget.textview.supertextview.SuperTextView
style="@style/InfoItem.Account"
app:sLeftTextString="账号" />
<com.xuexiang.xui.widget.textview.supertextview.SuperTextView
style="@style/InfoItem.Account"
app:sLeftTextString="通知" />
<com.xuexiang.xui.widget.textview.supertextview.SuperTextView
style="@style/InfoItem.Account"
app:sDividerLineType="none"
app:sLeftTextString="收藏" />
<com.xuexiang.xui.widget.textview.supertextview.SuperTextView
android:id="@+id/menu_advice"
style="@style/InfoItem.Account"
android:layout_marginTop="20dp"
app:sDividerLineType="none"
app:sLeftTextString="意见反馈" />
<com.xuexiang.xui.widget.textview.supertextview.SuperTextView
android:id="@+id/menu_settings"
style="@style/InfoItem.Account"
android:layout_marginTop="20dp"
app:sLeftTextString="设置" />
<com.xuexiang.xui.widget.textview.supertextview.SuperTextView
android:id="@+id/menu_about"
style="@style/InfoItem.Account"
app:sDividerLineType="none"
app:sLeftTextString="关于" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save