diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..639900d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..7252431 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/poem.iml b/.idea/poem.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/poem.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/doc/实践模板-开源软件泛读、标注和维护报告文档.docx b/doc/实践模板-开源软件泛读、标注和维护报告文档.docx new file mode 100644 index 0000000..46491d2 Binary files /dev/null and b/doc/实践模板-开源软件泛读、标注和维护报告文档.docx differ diff --git a/doc/系统设计分析第一次作业.docx b/doc/系统设计分析第一次作业.docx new file mode 100644 index 0000000..9f55070 Binary files /dev/null and b/doc/系统设计分析第一次作业.docx differ diff --git a/src/MyApplication/.gitignore b/src/MyApplication/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/src/MyApplication/.gitignore @@ -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 diff --git a/src/MyApplication/.idea/.gitignore b/src/MyApplication/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/src/MyApplication/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/src/MyApplication/.idea/.name b/src/MyApplication/.idea/.name new file mode 100644 index 0000000..e7cb646 --- /dev/null +++ b/src/MyApplication/.idea/.name @@ -0,0 +1 @@ +poem \ No newline at end of file diff --git a/src/MyApplication/.idea/compiler.xml b/src/MyApplication/.idea/compiler.xml new file mode 100644 index 0000000..fb7f4a8 --- /dev/null +++ b/src/MyApplication/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/MyApplication/.idea/gradle.xml b/src/MyApplication/.idea/gradle.xml new file mode 100644 index 0000000..7b46144 --- /dev/null +++ b/src/MyApplication/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/src/MyApplication/.idea/misc.xml b/src/MyApplication/.idea/misc.xml new file mode 100644 index 0000000..bdd9278 --- /dev/null +++ b/src/MyApplication/.idea/misc.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/MyApplication/.idea/vcs.xml b/src/MyApplication/.idea/vcs.xml new file mode 100644 index 0000000..b2bdec2 --- /dev/null +++ b/src/MyApplication/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/MyApplication/app/.gitignore b/src/MyApplication/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/src/MyApplication/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/src/MyApplication/app/build.gradle b/src/MyApplication/app/build.gradle new file mode 100644 index 0000000..a814057 --- /dev/null +++ b/src/MyApplication/app/build.gradle @@ -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" //sonar平台中相对应项目的key + 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' +} \ No newline at end of file diff --git a/src/MyApplication/app/proguard-rules.pro b/src/MyApplication/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/src/MyApplication/app/proguard-rules.pro @@ -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 \ No newline at end of file diff --git a/src/MyApplication/app/src/androidTest/java/com/example/myapplication/ExampleInstrumentedTest.java b/src/MyApplication/app/src/androidTest/java/com/example/myapplication/ExampleInstrumentedTest.java new file mode 100644 index 0000000..982ba51 --- /dev/null +++ b/src/MyApplication/app/src/androidTest/java/com/example/myapplication/ExampleInstrumentedTest.java @@ -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 Testing documentation + */ +@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()); + } +} \ No newline at end of file diff --git a/src/MyApplication/app/src/main/AndroidManifest.xml b/src/MyApplication/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..99713ef --- /dev/null +++ b/src/MyApplication/app/src/main/AndroidManifest.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/AdviceActivity.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/AdviceActivity.java new file mode 100644 index 0000000..9566797 --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/AdviceActivity.java @@ -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); + } +} \ No newline at end of file diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/ChatActivity.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/ChatActivity.java new file mode 100644 index 0000000..d534fff --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/ChatActivity.java @@ -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 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; + } + }; +} \ No newline at end of file diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/DetailActivity.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/DetailActivity.java new file mode 100644 index 0000000..49e3c90 --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/DetailActivity.java @@ -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 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 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() { + @Override + public void onResponse(retrofit2.Call call, retrofit2.Response response) { + try { + String responseData = response.body().string(); + parseJSONWithGSON(responseData); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onFailure(retrofit2.Call 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); + } + } +} \ No newline at end of file diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/LoginActivity.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/LoginActivity.java new file mode 100644 index 0000000..fe6e9d9 --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/LoginActivity.java @@ -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 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() { + @Override + public void onResponse(Call call, Response 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 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; + } + } + } +} \ No newline at end of file diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/MainActivity.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/MainActivity.java new file mode 100644 index 0000000..e67de41 --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/MainActivity.java @@ -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; + /** + *页面选中判断,当到达指定position时,返回position对应的页面 + */ + 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) { + /** + *当点击到菜单中的item时,调用viewPage中的setCurrentItem方法切换到对应界面 + */ + 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); + } + } +} \ No newline at end of file diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/PoetryListActivity.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/PoetryListActivity.java new file mode 100644 index 0000000..a4bc5d4 --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/PoetryListActivity.java @@ -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 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 poetries = gson.fromJson(temp, new TypeToken>() { + }.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 poetries = gson.fromJson(temp, new TypeToken>() { + }.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 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() { + @Override + public void onResponse(retrofit2.Call call, Response response) { + String responseData = null; + try { + responseData = response.body().string(); + } catch (IOException e) { + e.printStackTrace(); + } + parseJSONWithGSON(responseData); + } + + @Override + public void onFailure(Call 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 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() { + @Override + public void onResponse(retrofit2.Call call, Response response) { + String responseData = null; + try { + responseData = response.body().string(); + } catch (IOException e) { + e.printStackTrace(); + } + parseJSONWithGSON(responseData); + } + + @Override + public void onFailure(Call call, Throwable t) { + Toast.makeText(PoetryListActivity.this, "get回调失败", Toast.LENGTH_SHORT).show(); + } + }); + } + }).start(); + } + + private void parseJSONWithGSON(String jsonData) { + Gson gson = new Gson(); + List list = gson.fromJson(jsonData, new TypeToken>(){}.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); + } + } +} \ No newline at end of file diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/RegisterActivity.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/RegisterActivity.java new file mode 100644 index 0000000..11d26fe --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/RegisterActivity.java @@ -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 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() { + //请求成功时回调 + @Override + public void onResponse(Call call, Response 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 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; + } + } + } +} \ No newline at end of file diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/TestActivity.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/TestActivity.java new file mode 100644 index 0000000..275c76d --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Activity/TestActivity.java @@ -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 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() { + //图表设置 + Listlist=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 parts = builder.build().parts(); + //对 发送请求 进行封装 + Call call = request.getCall(parts); + call.enqueue(new Callback() { + //请求成功时回调 + @Override + public void onResponse(Call call, Response 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 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); + } + +} \ No newline at end of file diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Adapter/MsgAdapter.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Adapter/MsgAdapter.java new file mode 100644 index 0000000..7596301 --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Adapter/MsgAdapter.java @@ -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 { + private List 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 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(); + } + +} diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Adapter/PoemListAdapter.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Adapter/PoemListAdapter.java new file mode 100644 index 0000000..3d19281 --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Adapter/PoemListAdapter.java @@ -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 poetryList = new ArrayList(); + private Context context; + + public PoemListAdapter(List 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; + } + +} diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Adapter/RoomAdapter.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Adapter/RoomAdapter.java new file mode 100644 index 0000000..c02d960 --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Adapter/RoomAdapter.java @@ -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{ + List 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 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(); + } +} diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Api/Api.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Api/Api.java new file mode 100644 index 0000000..84856c8 --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Api/Api.java @@ -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 getData(@Query("username") String username, @Query("password") String password); + + @GET("user/register") + Call getRegisterData(@Query("username") String username, @Query("password") String password); + + @GET("poetry/getOnePoem") + Call getPoetry(); + + @GET("poetry/getByContentDetail") + Call getPoetryDetail(@Query("content") String content); + + @GET("poetry/getBySearch") + Call getPoetrys(@Query("key") String key, @Query("page") Integer page, @Query("size") Integer size); + + @GET("poetry/getAllDynasty") + Call getDynastyList(); + + @GET("poetry/getByTag") + Call getPoetrysByTag(@Query("dynasty") String dynasty, @Query("tag") String tag, @Query("page") Integer page, @Query("size") Integer size); + + @GET("poetry/generate") + Call createPoetry(@Query("form") String form, @Query("head") String head); + + //post请求 + @FormUrlEncoded + @POST("api/comments.163") + Call postDataCall(@Field("format") String format); + + @FormUrlEncoded + @POST("user/register") + Call registerCall(@Field("username") String username, @Field("password") String password); + +} diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Api/ToTrans.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Api/ToTrans.java new file mode 100644 index 0000000..28406b5 --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Api/ToTrans.java @@ -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 getCall(@Part List partList); + // @GET注解的作用:采用Get方法发送网络请求 + // getCall() = 接收网络请求数据的方法 + // 其中返回类型为Call<*>,*是接收数据的类(即上面定义的TranslationBean类),返回这个类的对象 +} + diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Constant/constant.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Constant/constant.java new file mode 100644 index 0000000..62fe725 --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Constant/constant.java @@ -0,0 +1,6 @@ +package com.example.myapplication.Constant; + +public class constant { + public static final String poetry_IP = "http://101.33.242.218:8081/"; + +} \ No newline at end of file diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Fragment/AiPoetry/AiPoetryFragment.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Fragment/AiPoetry/AiPoetryFragment.java new file mode 100644 index 0000000..bd9b401 --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Fragment/AiPoetry/AiPoetryFragment.java @@ -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 poem_tags; + private TagFlowLayout poem_style_flow; + + private HashMap poem_type; + private HashMap poem_style; + private HashMap selectedTag = new HashMap<>(); + + private List 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 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() { + @Override + public void onResponse(retrofit2.Call call, retrofit2.Response 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 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(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(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 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; + } +} \ No newline at end of file diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Fragment/My/MyFragment.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Fragment/My/MyFragment.java new file mode 100644 index 0000000..4cc437b --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Fragment/My/MyFragment.java @@ -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; + } +} \ No newline at end of file diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Fragment/Search/SearchFragment.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Fragment/Search/SearchFragment.java new file mode 100644 index 0000000..d0cb45b --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Fragment/Search/SearchFragment.java @@ -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 selectedType = new ArrayList(); + private List selectedStyle = new ArrayList(); + private List selectedDynasty = new ArrayList(); + + 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(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(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(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 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; + } +} \ No newline at end of file diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Fragment/association/AssociationFragment.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Fragment/association/AssociationFragment.java new file mode 100644 index 0000000..913d1cf --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Fragment/association/AssociationFragment.java @@ -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 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 list = gson.fromJson(res, new TypeToken>() { + }.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 list = gson.fromJson(res, new TypeToken>() { + }.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; + } +} \ No newline at end of file diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Fragment/home/HomeFragment.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Fragment/home/HomeFragment.java new file mode 100644 index 0000000..2656c96 --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Fragment/home/HomeFragment.java @@ -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 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() { + @Override + public void onResponse(retrofit2.Call call, retrofit2.Response 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 call, Throwable t) { + Toast.makeText(getContext(), "获取每日诗词失败", Toast.LENGTH_SHORT).show(); + } + }); + } + }).start(); + } + @Override + public void onDestroyView() { + super.onDestroyView(); + binding = null; + } +} \ No newline at end of file diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/ClientMessageBean.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/ClientMessageBean.java new file mode 100644 index 0000000..7fb5b3b --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/ClientMessageBean.java @@ -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; + } +} diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/Data.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/Data.java new file mode 100644 index 0000000..f271b6c --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/Data.java @@ -0,0 +1,36 @@ +package com.example.myapplication.Modal; + +/** + * @创建者 晏嘉琳 + * @创建时间 2023/5/31 18:16 + * @类描述 ${TODO}步骤三:回调数据统一封装类 + */ +public class Data { + 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; + } +} diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/EmotionResBean.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/EmotionResBean.java new file mode 100644 index 0000000..f2fb322 --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/EmotionResBean.java @@ -0,0 +1,32 @@ +package com.example.myapplication.Modal; + +import java.util.List; + +public class EmotionResBean { + private String emotion ; + private List prob; + + public EmotionResBean() { + } + + public EmotionResBean(String emotion, List prob) { + this.emotion = emotion; + this.prob = prob; + } + + public String getEmotion() { + return emotion; + } + + public void setEmotion(String emotion) { + this.emotion = emotion; + } + + public List getList() { + return prob; + } + + public void setList(List list) { + this.prob = list; + } +} diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/Poetry.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/Poetry.java new file mode 100644 index 0000000..0a09f2d --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/Poetry.java @@ -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; + } +} diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/PoetryDetail.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/PoetryDetail.java new file mode 100644 index 0000000..2e80ef3 --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/PoetryDetail.java @@ -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; + } +} diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/PoetryUtil.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/PoetryUtil.java new file mode 100644 index 0000000..b6ba344 --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/PoetryUtil.java @@ -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 styles = Arrays.asList("五言", "七言"); + static List poem_tags = Arrays.asList("绝句", "律诗"); + + static HashMap poem_type = new HashMap(); + + static { + poem_type.put("绝句", "绝句"); + poem_type.put("律诗", "律诗"); + } + + static HashMap poemStyle = new HashMap(); + + static { + poemStyle.put("五言", "五言"); + poemStyle.put("七言", "七言"); + } + + static List ci_pai = Arrays.asList("归字谣", "如梦令", "梧桐影", "渔歌子", "捣练子", "忆江南", "忆王孙", "河满子"); + + static String[] type = + { + "诗", + "词", + "曲", + "文言文" + }; + + static String[] dynasty = { + "两汉", + "五代", + "元代", + "先秦", + "南北朝", + "唐代", + "宋代", + "当代", + "明代", + "未知", + "清代", + "现代", + "近代", + "金朝", + "隋代", + "魏晋" + }; + + static String[] style = { + "写景", + "咏物", + "春天", + "夏天", + "秋天", + "冬天", + "写雨", + "写雪", + "写风", + "写花", + "梅花", + "荷花", + "菊花", + "柳树", + "月亮", + "山水", + "写山", + "写水", + "长江", + "黄河", + "儿童", + "写鸟", + "写马", + "田园", + "边塞", + "地名", + "抒情", + "爱国", + "离别", + "送别", + "思乡", + "思念", + "爱情", + "励志", + "哲理", + "闺怨", + "悼亡", + "写人", + "老师", + "母亲", + "友情", + "战争", + "读书", + "惜时", + "婉约", + "豪放", + "诗经", + "民谣", + "节日", + "春节", + "元宵节", + "寒食节", + "清明节", + "端午节", + "七夕节", + "中秋节", + "重阳节", + "忧国忧民", + "咏史怀古", + "宋词精选", + "小学古诗", + "初中古诗", + "高中古诗", + "小学文言文", + "初中文言文", + "高中文言文", + "古诗十九首", + "唐诗三百首", + "古诗三百首", + "宋词三百首" + }; + + + public static List getTypeList() { + List typeTagList = new ArrayList(); + typeTagList.add("诗"); + typeTagList.add("词"); + typeTagList.add("曲"); + typeTagList.add("文言文"); + return typeTagList; + } + + public static String[] getDynastyList() { + + List dynastyList = new ArrayList(); + + 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 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() { + @Override + public void onResponse(retrofit2.Call call, retrofit2.Response 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(){}.getType()); + dynastyList.addAll(list); + } + + @Override + public void onFailure(retrofit2.Call call, Throwable t) { + t.printStackTrace(); + } + }); + } + }); + thread_dynasty.start(); + return dynastyList.toArray(new String[dynastyList.size()]); + } + + public static List getStyleList() { + + List styleList = new ArrayList(); + +// 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 getStyles() { + return styles; + } + + public static List getPoemTags() { + return poem_tags; + } + + public static List getCiPai() { + return ci_pai; + } + + public static HashMap getPoemType() { + return poem_type; + } + + public static HashMap getPoemStyle() { + return poemStyle; + } + +} diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/PrivateInfo.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/PrivateInfo.java new file mode 100644 index 0000000..b2d21fd --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/PrivateInfo.java @@ -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 = ""; + +} diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/RoomBean.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/RoomBean.java new file mode 100644 index 0000000..875fd4d --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/RoomBean.java @@ -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() { + } +} diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/SystemMessageBean.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/SystemMessageBean.java new file mode 100644 index 0000000..4da4415 --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Modal/SystemMessageBean.java @@ -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; + } +} diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Util/FileUtils.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Util/FileUtils.java new file mode 100644 index 0000000..3a0605b --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Util/FileUtils.java @@ -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(); + } + } + } + } + +} diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Util/Spilt.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Util/Spilt.java new file mode 100644 index 0000000..97aecf0 --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Util/Spilt.java @@ -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; + } + +} diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/Util/WebSocketUtil.java b/src/MyApplication/app/src/main/java/com/example/myapplication/Util/WebSocketUtil.java new file mode 100644 index 0000000..79a1a3b --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/Util/WebSocketUtil.java @@ -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 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); + } +} + diff --git a/src/MyApplication/app/src/main/java/com/example/myapplication/XUIInit.java b/src/MyApplication/app/src/main/java/com/example/myapplication/XUIInit.java new file mode 100644 index 0000000..cfc7890 --- /dev/null +++ b/src/MyApplication/app/src/main/java/com/example/myapplication/XUIInit.java @@ -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); + } +} \ No newline at end of file diff --git a/src/MyApplication/app/src/main/res/color/selector_round_button_main_theme_color.xml b/src/MyApplication/app/src/main/res/color/selector_round_button_main_theme_color.xml new file mode 100644 index 0000000..16fd2c7 --- /dev/null +++ b/src/MyApplication/app/src/main/res/color/selector_round_button_main_theme_color.xml @@ -0,0 +1,24 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/MyApplication/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/src/MyApplication/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/src/MyApplication/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/MyApplication/app/src/main/res/drawable/advice.png b/src/MyApplication/app/src/main/res/drawable/advice.png new file mode 100644 index 0000000..ad38082 Binary files /dev/null and b/src/MyApplication/app/src/main/res/drawable/advice.png differ diff --git a/src/MyApplication/app/src/main/res/drawable/app.jpg b/src/MyApplication/app/src/main/res/drawable/app.jpg new file mode 100644 index 0000000..d70a5c5 Binary files /dev/null and b/src/MyApplication/app/src/main/res/drawable/app.jpg differ diff --git a/src/MyApplication/app/src/main/res/drawable/bg_rect_round_blue.xml b/src/MyApplication/app/src/main/res/drawable/bg_rect_round_blue.xml new file mode 100644 index 0000000..24ee461 --- /dev/null +++ b/src/MyApplication/app/src/main/res/drawable/bg_rect_round_blue.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/MyApplication/app/src/main/res/drawable/border.xml b/src/MyApplication/app/src/main/res/drawable/border.xml new file mode 100644 index 0000000..9922a6e --- /dev/null +++ b/src/MyApplication/app/src/main/res/drawable/border.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/MyApplication/app/src/main/res/drawable/chatroom_temp.png b/src/MyApplication/app/src/main/res/drawable/chatroom_temp.png new file mode 100644 index 0000000..e99a7d9 Binary files /dev/null and b/src/MyApplication/app/src/main/res/drawable/chatroom_temp.png differ diff --git a/src/MyApplication/app/src/main/res/drawable/create_room.png b/src/MyApplication/app/src/main/res/drawable/create_room.png new file mode 100644 index 0000000..b522547 Binary files /dev/null and b/src/MyApplication/app/src/main/res/drawable/create_room.png differ diff --git a/src/MyApplication/app/src/main/res/drawable/dynasty_label_style.xml b/src/MyApplication/app/src/main/res/drawable/dynasty_label_style.xml new file mode 100644 index 0000000..54d71fb --- /dev/null +++ b/src/MyApplication/app/src/main/res/drawable/dynasty_label_style.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/src/MyApplication/app/src/main/res/drawable/editstyle.xml b/src/MyApplication/app/src/main/res/drawable/editstyle.xml new file mode 100644 index 0000000..e1b6a03 --- /dev/null +++ b/src/MyApplication/app/src/main/res/drawable/editstyle.xml @@ -0,0 +1,17 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/MyApplication/app/src/main/res/drawable/ic_back.png b/src/MyApplication/app/src/main/res/drawable/ic_back.png new file mode 100644 index 0000000..4b0551e Binary files /dev/null and b/src/MyApplication/app/src/main/res/drawable/ic_back.png differ diff --git a/src/MyApplication/app/src/main/res/drawable/ic_dashboard_black_24dp.xml b/src/MyApplication/app/src/main/res/drawable/ic_dashboard_black_24dp.xml new file mode 100644 index 0000000..46fc8de --- /dev/null +++ b/src/MyApplication/app/src/main/res/drawable/ic_dashboard_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/src/MyApplication/app/src/main/res/drawable/ic_default_head.xml b/src/MyApplication/app/src/main/res/drawable/ic_default_head.xml new file mode 100644 index 0000000..f68423e --- /dev/null +++ b/src/MyApplication/app/src/main/res/drawable/ic_default_head.xml @@ -0,0 +1,26 @@ + + + + + diff --git a/src/MyApplication/app/src/main/res/drawable/ic_home_black_24dp.xml b/src/MyApplication/app/src/main/res/drawable/ic_home_black_24dp.xml new file mode 100644 index 0000000..f8bb0b5 --- /dev/null +++ b/src/MyApplication/app/src/main/res/drawable/ic_home_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/src/MyApplication/app/src/main/res/drawable/ic_launcher_background.xml b/src/MyApplication/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/src/MyApplication/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/MyApplication/app/src/main/res/drawable/ic_navigate1.png b/src/MyApplication/app/src/main/res/drawable/ic_navigate1.png new file mode 100644 index 0000000..bccb0eb Binary files /dev/null and b/src/MyApplication/app/src/main/res/drawable/ic_navigate1.png differ diff --git a/src/MyApplication/app/src/main/res/drawable/ic_notifications_black_24dp.xml b/src/MyApplication/app/src/main/res/drawable/ic_notifications_black_24dp.xml new file mode 100644 index 0000000..78b75c3 --- /dev/null +++ b/src/MyApplication/app/src/main/res/drawable/ic_notifications_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/src/MyApplication/app/src/main/res/drawable/ic_password.xml b/src/MyApplication/app/src/main/res/drawable/ic_password.xml new file mode 100644 index 0000000..716e402 --- /dev/null +++ b/src/MyApplication/app/src/main/res/drawable/ic_password.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/src/MyApplication/app/src/main/res/drawable/ic_phone.xml b/src/MyApplication/app/src/main/res/drawable/ic_phone.xml new file mode 100644 index 0000000..56cf551 --- /dev/null +++ b/src/MyApplication/app/src/main/res/drawable/ic_phone.xml @@ -0,0 +1,4 @@ + + + diff --git a/src/MyApplication/app/src/main/res/drawable/ic_search.png b/src/MyApplication/app/src/main/res/drawable/ic_search.png new file mode 100644 index 0000000..4926e5d Binary files /dev/null and b/src/MyApplication/app/src/main/res/drawable/ic_search.png differ diff --git a/src/MyApplication/app/src/main/res/drawable/ic_setting.png b/src/MyApplication/app/src/main/res/drawable/ic_setting.png new file mode 100644 index 0000000..84ca126 Binary files /dev/null and b/src/MyApplication/app/src/main/res/drawable/ic_setting.png differ diff --git a/src/MyApplication/app/src/main/res/drawable/icon_arrow_right_grey.xml b/src/MyApplication/app/src/main/res/drawable/icon_arrow_right_grey.xml new file mode 100644 index 0000000..964e9b2 --- /dev/null +++ b/src/MyApplication/app/src/main/res/drawable/icon_arrow_right_grey.xml @@ -0,0 +1,29 @@ + + + + + + diff --git a/src/MyApplication/app/src/main/res/drawable/icon_collect1.png b/src/MyApplication/app/src/main/res/drawable/icon_collect1.png new file mode 100644 index 0000000..2e93c83 Binary files /dev/null and b/src/MyApplication/app/src/main/res/drawable/icon_collect1.png differ diff --git a/src/MyApplication/app/src/main/res/drawable/img.png b/src/MyApplication/app/src/main/res/drawable/img.png new file mode 100644 index 0000000..9daa78d Binary files /dev/null and b/src/MyApplication/app/src/main/res/drawable/img.png differ diff --git a/src/MyApplication/app/src/main/res/drawable/img_1.png b/src/MyApplication/app/src/main/res/drawable/img_1.png new file mode 100644 index 0000000..9daa78d Binary files /dev/null and b/src/MyApplication/app/src/main/res/drawable/img_1.png differ diff --git a/src/MyApplication/app/src/main/res/drawable/img_2.png b/src/MyApplication/app/src/main/res/drawable/img_2.png new file mode 100644 index 0000000..9daa78d Binary files /dev/null and b/src/MyApplication/app/src/main/res/drawable/img_2.png differ diff --git a/src/MyApplication/app/src/main/res/drawable/label_style.xml b/src/MyApplication/app/src/main/res/drawable/label_style.xml new file mode 100644 index 0000000..eee0295 --- /dev/null +++ b/src/MyApplication/app/src/main/res/drawable/label_style.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/src/MyApplication/app/src/main/res/drawable/message_center.9.png b/src/MyApplication/app/src/main/res/drawable/message_center.9.png new file mode 100644 index 0000000..29eddb9 Binary files /dev/null and b/src/MyApplication/app/src/main/res/drawable/message_center.9.png differ diff --git a/src/MyApplication/app/src/main/res/drawable/message_left.9.png b/src/MyApplication/app/src/main/res/drawable/message_left.9.png new file mode 100644 index 0000000..1427e9d Binary files /dev/null and b/src/MyApplication/app/src/main/res/drawable/message_left.9.png differ diff --git a/src/MyApplication/app/src/main/res/drawable/message_right.9.png b/src/MyApplication/app/src/main/res/drawable/message_right.9.png new file mode 100644 index 0000000..1c0eda7 Binary files /dev/null and b/src/MyApplication/app/src/main/res/drawable/message_right.9.png differ diff --git a/src/MyApplication/app/src/main/res/drawable/round_editstyle.xml b/src/MyApplication/app/src/main/res/drawable/round_editstyle.xml new file mode 100644 index 0000000..c36f014 --- /dev/null +++ b/src/MyApplication/app/src/main/res/drawable/round_editstyle.xml @@ -0,0 +1,17 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/MyApplication/app/src/main/res/drawable/search.png b/src/MyApplication/app/src/main/res/drawable/search.png new file mode 100644 index 0000000..bacdec4 Binary files /dev/null and b/src/MyApplication/app/src/main/res/drawable/search.png differ diff --git a/src/MyApplication/app/src/main/res/drawable/type_label_style.xml b/src/MyApplication/app/src/main/res/drawable/type_label_style.xml new file mode 100644 index 0000000..11b1e1a --- /dev/null +++ b/src/MyApplication/app/src/main/res/drawable/type_label_style.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/src/MyApplication/app/src/main/res/drawable/voice.png b/src/MyApplication/app/src/main/res/drawable/voice.png new file mode 100644 index 0000000..f07a2a5 Binary files /dev/null and b/src/MyApplication/app/src/main/res/drawable/voice.png differ diff --git a/src/MyApplication/app/src/main/res/layout/activity_advice.xml b/src/MyApplication/app/src/main/res/layout/activity_advice.xml new file mode 100644 index 0000000..16f1515 --- /dev/null +++ b/src/MyApplication/app/src/main/res/layout/activity_advice.xml @@ -0,0 +1,33 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/MyApplication/app/src/main/res/layout/activity_detail.xml b/src/MyApplication/app/src/main/res/layout/activity_detail.xml new file mode 100644 index 0000000..1337336 --- /dev/null +++ b/src/MyApplication/app/src/main/res/layout/activity_detail.xml @@ -0,0 +1,384 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/MyApplication/app/src/main/res/layout/activity_login.xml b/src/MyApplication/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..6d652b1 --- /dev/null +++ b/src/MyApplication/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/MyApplication/app/src/main/res/layout/activity_main.xml b/src/MyApplication/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..0bd11c6 --- /dev/null +++ b/src/MyApplication/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/MyApplication/app/src/main/res/layout/activity_poetry_list.xml b/src/MyApplication/app/src/main/res/layout/activity_poetry_list.xml new file mode 100644 index 0000000..d669206 --- /dev/null +++ b/src/MyApplication/app/src/main/res/layout/activity_poetry_list.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/MyApplication/app/src/main/res/layout/activity_register.xml b/src/MyApplication/app/src/main/res/layout/activity_register.xml new file mode 100644 index 0000000..f9601ba --- /dev/null +++ b/src/MyApplication/app/src/main/res/layout/activity_register.xml @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/MyApplication/app/src/main/res/layout/activity_test.xml b/src/MyApplication/app/src/main/res/layout/activity_test.xml new file mode 100644 index 0000000..6a69b98 --- /dev/null +++ b/src/MyApplication/app/src/main/res/layout/activity_test.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + +