AI功能基本实现完毕,但目前仅是非流式回答,另外实现了返回上一界面的原来位置
This commit is contained in:
parent
54a8a8304d
commit
39b978b749
@ -33,10 +33,10 @@ class Author_introductionActivity : AppCompatActivity() {
|
||||
authorwork_recyclerView.adapter = adapter
|
||||
inits()
|
||||
author_back.setOnClickListener {
|
||||
val bookName=intent.getStringExtra("book_name")
|
||||
val intent = Intent(this, BookInformationActivity::class.java)
|
||||
intent.putExtra("Book_name", bookName)
|
||||
startActivity(intent)
|
||||
// val bookName=intent.getStringExtra("book_name")
|
||||
// val intent = Intent(this, BookInformationActivity::class.java)
|
||||
// intent.putExtra("Book_name", bookName)
|
||||
// startActivity(intent)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
@ -156,15 +156,15 @@ class BookInformationActivity : AppCompatActivity() {
|
||||
}
|
||||
//TODO:不一定回到MainActivity::class,后面还要在跳转前保存上一个页面
|
||||
bookinfo_return.setOnClickListener {
|
||||
if (sourceActivityClass != null) {
|
||||
// 返回到上一个页面
|
||||
val intent = Intent(this, sourceActivityClass!!)
|
||||
startActivity(intent)
|
||||
} else {
|
||||
// 如果没有来源页面信息,则返回到 MainActivity
|
||||
val intent = Intent(this, MainActivity::class.java)
|
||||
startActivity(intent)
|
||||
}
|
||||
// if (sourceActivityClass != null) {
|
||||
// // 返回到上一个页面
|
||||
// val intent = Intent(this, sourceActivityClass!!)
|
||||
// startActivity(intent)
|
||||
// } else {
|
||||
// // 如果没有来源页面信息,则返回到 MainActivity
|
||||
// val intent = Intent(this, MainActivity::class.java)
|
||||
// startActivity(intent)
|
||||
// }
|
||||
finish()
|
||||
}
|
||||
addBook2.setOnClickListener {
|
||||
|
@ -92,8 +92,8 @@ class GoodBookActivity : AppCompatActivity() {
|
||||
}
|
||||
private fun returnTOCity() {
|
||||
bookrank_return.setOnClickListener {
|
||||
val intent = Intent(this, MainActivity::class.java)
|
||||
startActivity(intent)
|
||||
// val intent = Intent(this, MainActivity::class.java)
|
||||
// startActivity(intent)
|
||||
finish() // 结束当前页面
|
||||
}
|
||||
}
|
||||
|
@ -79,8 +79,8 @@ class HotBookActivity: AppCompatActivity() {
|
||||
//TODO:未来添加一个返回到上个页面指定位置的功能
|
||||
private fun returnTOCity() {
|
||||
bookrank_return.setOnClickListener {
|
||||
val intent = Intent(this, MainActivity::class.java)
|
||||
startActivity(intent)
|
||||
// val intent = Intent(this, MainActivity::class.java)
|
||||
// startActivity(intent)
|
||||
finish() // 结束当前页面
|
||||
}
|
||||
}
|
||||
|
@ -97,7 +97,8 @@ class LiteratureActivity : AppCompatActivity() {
|
||||
}
|
||||
private fun returnToBookcity(){
|
||||
categoryPage_back.setOnClickListener{
|
||||
startActivity(Intent(this, MainActivity::class.java))
|
||||
// startActivity(Intent(this, MainActivity::class.java))
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,8 @@ class ManagementActivity:AppCompatActivity() {
|
||||
}
|
||||
private fun returnToBookcity(){
|
||||
categoryPage_back.setOnClickListener{
|
||||
startActivity(Intent(this, MainActivity::class.java))
|
||||
// startActivity(Intent(this, MainActivity::class.java))
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,8 @@ class PhilosophyActivity:AppCompatActivity() {
|
||||
}
|
||||
private fun returnToBookcity(){
|
||||
categoryPage_back.setOnClickListener{
|
||||
startActivity(Intent(this, MainActivity::class.java))
|
||||
// startActivity(Intent(this, MainActivity::class.java))
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,8 @@ class PsychologyActivity:AppCompatActivity() {
|
||||
}
|
||||
private fun returnToBookcity(){
|
||||
categoryPage_back.setOnClickListener{
|
||||
startActivity(Intent(this, MainActivity::class.java))
|
||||
// startActivity(Intent(this, MainActivity::class.java))
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,8 @@ class ScienceActivity:AppCompatActivity() {
|
||||
}
|
||||
private fun returnToBookcity(){
|
||||
categoryPage_back.setOnClickListener{
|
||||
startActivity(Intent(this, MainActivity::class.java))
|
||||
// startActivity(Intent(this, MainActivity::class.java))
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:padding="8dp"
|
||||
android:padding="4dp"
|
||||
android:src="@drawable/return1" />
|
||||
|
||||
<TextView
|
||||
|
@ -19,8 +19,9 @@
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/categoryPage_back"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:padding="4dp"
|
||||
android:src="@drawable/return1" />
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -8,6 +8,7 @@
|
||||
android:id="@+id/bookinfo_return"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:padding="4dp"
|
||||
android:src="@drawable/return1" />
|
||||
|
||||
<TextView
|
||||
|
@ -1,12 +1,17 @@
|
||||
package com.bifan.txtreaderlib.adapter;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.bifan.txtreaderlib.R;
|
||||
import com.bifan.txtreaderlib.bean.Message;
|
||||
|
||||
@ -14,9 +19,19 @@ import java.util.List;
|
||||
|
||||
public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.MessageViewHolder> {
|
||||
private List<Message> messages;
|
||||
private Context context;
|
||||
private OnRegenerateClickListener onRegenerateClickListener;
|
||||
public void setOnRegenerateClickListener(OnRegenerateClickListener listener) {
|
||||
this.onRegenerateClickListener = listener;
|
||||
}
|
||||
|
||||
public MessageAdapter(List<Message> messages) {
|
||||
public interface OnRegenerateClickListener {
|
||||
void onRegenerateClick(int position);
|
||||
}
|
||||
|
||||
public MessageAdapter(List<Message> messages, Context context) {
|
||||
this.messages = messages;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -38,17 +53,52 @@ public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.MessageV
|
||||
return new MessageViewHolder(view, viewType);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull MessageViewHolder holder, int position) {
|
||||
public void onBindViewHolder(@NonNull MessageViewHolder holder, @SuppressLint("RecyclerView") int position) {
|
||||
Message message = messages.get(position);
|
||||
if (message.getIsuser() == 1) {
|
||||
if (message.getIsuser() == 1) { // user
|
||||
holder.textViewMessage.setText(message.getContent());
|
||||
} else {
|
||||
} else { // bot
|
||||
holder.textViewMessage.setText(message.getContent());
|
||||
// 检查是否为最后一条机器人消息
|
||||
if (position == getLastBotMessagePosition()) {
|
||||
holder.imageViewRegenerate.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.imageViewRegenerate.setVisibility(View.GONE);
|
||||
}
|
||||
setupClickListeners(holder, message, position);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取最后一条机器人消息的位置
|
||||
public int getLastBotMessagePosition() {
|
||||
for (int i = messages.size() - 1; i >= 0; i--) {
|
||||
if (messages.get(i).getIsuser() == 0) { // Assuming 0 is the bot
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void setupClickListeners(MessageViewHolder holder, Message message, int position) {
|
||||
holder.imageViewCopy.setOnClickListener(v -> {
|
||||
copyTextToClipboard(message.getContent());
|
||||
});
|
||||
|
||||
holder.imageViewRegenerate.setOnClickListener(view -> {
|
||||
if (onRegenerateClickListener != null) {
|
||||
onRegenerateClickListener.onRegenerateClick(position);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void copyTextToClipboard(String text) {
|
||||
ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
ClipData clipData = ClipData.newPlainText("copiedText", text);
|
||||
clipboardManager.setPrimaryClip(clipData);
|
||||
Toast.makeText(context, "已复制到剪贴板", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return messages.size();
|
||||
@ -56,14 +106,17 @@ public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.MessageV
|
||||
|
||||
static class MessageViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView textViewMessage;
|
||||
|
||||
ImageView imageViewCopy;
|
||||
ImageView imageViewRegenerate;
|
||||
MessageViewHolder(View itemView, int viewType) {
|
||||
super(itemView);
|
||||
if (viewType == 1) { // 假设 1 是用户消息
|
||||
textViewMessage = itemView.findViewById(R.id.textViewMessageUser);
|
||||
} else { // 非 1 即机器人消息
|
||||
textViewMessage = itemView.findViewById(R.id.textViewMessageBot);
|
||||
imageViewCopy = itemView.findViewById(R.id.imageViewCopy);
|
||||
imageViewRegenerate=itemView.findViewById(R.id.imageViewRegenerate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,10 @@ public class ChatMessage_bmob extends BmobObject {
|
||||
private String relatedBook;
|
||||
private String userid;
|
||||
|
||||
public ChatMessage_bmob() {
|
||||
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
@ -32,6 +32,14 @@ public class ChatResponse {
|
||||
String model;
|
||||
public List<Choice> choices;
|
||||
|
||||
public List<Choice> getChoices() {
|
||||
return choices;
|
||||
}
|
||||
|
||||
public void setChoices(List<Choice> choices) {
|
||||
this.choices = choices;
|
||||
}
|
||||
|
||||
public static class Choice {
|
||||
int index;
|
||||
public Message message;
|
||||
|
@ -0,0 +1,60 @@
|
||||
package com.bifan.txtreaderlib.bean;
|
||||
|
||||
import cn.bmob.v3.BmobObject;
|
||||
|
||||
public class GenerateQue_bmob extends BmobObject {
|
||||
private String relatedBook;
|
||||
private String userid;
|
||||
private String ques1;
|
||||
private String ques2;
|
||||
private String ques3;
|
||||
|
||||
public GenerateQue_bmob(String relatedBook, String userid, String ques1, String ques2, String ques3) {
|
||||
this.relatedBook = relatedBook;
|
||||
this.userid = userid;
|
||||
this.ques1 = ques1;
|
||||
this.ques2 = ques2;
|
||||
this.ques3 = ques3;
|
||||
}
|
||||
public GenerateQue_bmob(){}
|
||||
|
||||
public String getRelatedBook() {
|
||||
return relatedBook;
|
||||
}
|
||||
|
||||
public void setRelatedBook(String relatedBook) {
|
||||
this.relatedBook = relatedBook;
|
||||
}
|
||||
|
||||
public String getUserid() {
|
||||
return userid;
|
||||
}
|
||||
|
||||
public void setUserid(String userid) {
|
||||
this.userid = userid;
|
||||
}
|
||||
|
||||
public String getQues1() {
|
||||
return ques1;
|
||||
}
|
||||
|
||||
public void setQues1(String ques1) {
|
||||
this.ques1 = ques1;
|
||||
}
|
||||
|
||||
public String getQues2() {
|
||||
return ques2;
|
||||
}
|
||||
|
||||
public void setQues2(String ques2) {
|
||||
this.ques2 = ques2;
|
||||
}
|
||||
|
||||
public String getQues3() {
|
||||
return ques3;
|
||||
}
|
||||
|
||||
public void setQues3(String ques3) {
|
||||
this.ques3 = ques3;
|
||||
}
|
||||
}
|
@ -1,16 +1,21 @@
|
||||
package com.bifan.txtreaderlib.ui;
|
||||
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.widget.NestedScrollView;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
@ -19,6 +24,7 @@ import com.bifan.txtreaderlib.adapter.MessageAdapter;
|
||||
import com.bifan.txtreaderlib.bean.ChatMessage_bmob;
|
||||
import com.bifan.txtreaderlib.bean.ChatRequest;
|
||||
import com.bifan.txtreaderlib.bean.ChatResponse;
|
||||
import com.bifan.txtreaderlib.bean.GenerateQue_bmob;
|
||||
import com.bifan.txtreaderlib.bean.Message;
|
||||
import com.bifan.txtreaderlib.interfaces.ChatGPTService;
|
||||
|
||||
@ -26,14 +32,18 @@ import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import cn.bmob.v3.Bmob;
|
||||
import cn.bmob.v3.BmobQuery;
|
||||
import cn.bmob.v3.exception.BmobException;
|
||||
import cn.bmob.v3.listener.FindListener;
|
||||
import cn.bmob.v3.listener.SaveListener;
|
||||
import cn.bmob.v3.listener.UpdateListener;
|
||||
import okhttp3.OkHttpClient;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
@ -41,15 +51,17 @@ import retrofit2.Response;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
|
||||
public class ChatWithGptActivity extends AppCompatActivity {
|
||||
public class ChatWithGptActivity extends AppCompatActivity implements MessageAdapter.OnRegenerateClickListener {
|
||||
private RecyclerView recyclerView;
|
||||
private MessageAdapter messageAdapter;
|
||||
private EditText editTextMessage;
|
||||
private TextView chatbot_title;
|
||||
private Button buttonSend;
|
||||
private ImageView buttonSend,chat_return;
|
||||
private String bookName = "";
|
||||
private String userid="";
|
||||
private String userid = "";
|
||||
private String lastUserQuestion = ""; // 全局变量来存储最后一条用户消息
|
||||
private ArrayList<Message> messageList = new ArrayList<>();
|
||||
private TextView questionView1, questionView2, questionView3;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
@ -62,41 +74,99 @@ public class ChatWithGptActivity extends AppCompatActivity {
|
||||
SharedPreferences sharedPreferences = getSharedPreferences("userinf", Context.MODE_PRIVATE);
|
||||
String userIdFromPrefs = sharedPreferences.getString("user_id", "");
|
||||
userid = userIdFromPrefs != null ? userIdFromPrefs : "";
|
||||
|
||||
recyclerView = findViewById(R.id.chatRecyclerView);
|
||||
editTextMessage = findViewById(R.id.inputEditText);
|
||||
buttonSend = findViewById(R.id.sendButton);
|
||||
chatbot_title=findViewById(R.id.chatbot_title);
|
||||
messageAdapter = new MessageAdapter(messageList);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
recyclerView.setAdapter(messageAdapter);
|
||||
setupViews();
|
||||
init();
|
||||
buttonSend.setOnClickListener(new View.OnClickListener() {
|
||||
initgenerateUserQuestions();
|
||||
loadLastUserMessage();
|
||||
setupListeners();
|
||||
}
|
||||
|
||||
private void setupListeners() {
|
||||
buttonSend.setOnClickListener(v -> sendandStoreMessage(editTextMessage.getText().toString()));
|
||||
|
||||
View.OnClickListener questionClickListener = view -> {
|
||||
TextView questionView = (TextView) view;
|
||||
String message = questionView.getText().toString();
|
||||
clearQuestionsVisibility();
|
||||
sendandStoreMessage(message);
|
||||
};
|
||||
|
||||
questionView1.setOnClickListener(questionClickListener);
|
||||
questionView2.setOnClickListener(questionClickListener);
|
||||
questionView3.setOnClickListener(questionClickListener);
|
||||
chat_return.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
String text = editTextMessage.getText().toString();
|
||||
if (!text.isEmpty()) {
|
||||
messageList.add(new Message(text, 1)); // User message
|
||||
messageAdapter.notifyItemInserted(messageList.size() - 1);
|
||||
recyclerView.scrollToPosition(messageList.size() - 1);
|
||||
editTextMessage.setText("");
|
||||
sendMessageToChatGPT(text);
|
||||
ChatMessage_bmob chatMessage_bmob=new ChatMessage_bmob(text,1,bookName,userid);
|
||||
chatMessage_bmob.save(new SaveListener<String>() {
|
||||
@Override
|
||||
public void done(String objectId,BmobException e) {
|
||||
if(e==null){
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void clearQuestionsVisibility() {
|
||||
questionView1.setVisibility(View.GONE);
|
||||
questionView2.setVisibility(View.GONE);
|
||||
questionView3.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
private void sendandStoreMessage(String text) {
|
||||
messageList.add(new Message(text, 1)); // User message
|
||||
messageAdapter.notifyItemInserted(messageList.size() - 1);
|
||||
editTextMessage.setText("");
|
||||
sendMessageToChatGPT(text);
|
||||
lastUserQuestion=text;
|
||||
storeMessage(text,1);
|
||||
}
|
||||
private void storeMessage(String text,int isuser){
|
||||
ChatMessage_bmob chatMessage_bmob = new ChatMessage_bmob(text, isuser, bookName, userid);
|
||||
chatMessage_bmob.save(new SaveListener<String>() {
|
||||
@Override
|
||||
public void done(String objectId, BmobException e) {
|
||||
if (e == null) {
|
||||
// toast("添加数据成功,返回objectId为:"+objectId);
|
||||
}else{
|
||||
//toast("创建数据失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
//toast("创建数据失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
private void init(){
|
||||
|
||||
private void setupViews() {
|
||||
recyclerView = findViewById(R.id.chatRecyclerView);
|
||||
editTextMessage = findViewById(R.id.inputEditText);
|
||||
buttonSend = findViewById(R.id.sendButton);
|
||||
chatbot_title = findViewById(R.id.chatbot_title);
|
||||
questionView1 = findViewById(R.id.question1);
|
||||
questionView2 = findViewById(R.id.question2);
|
||||
questionView3 = findViewById(R.id.question3);
|
||||
chat_return=findViewById(R.id.chat_return);
|
||||
messageAdapter = new MessageAdapter(messageList, this);
|
||||
messageAdapter.setOnRegenerateClickListener(this);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
recyclerView.setAdapter(messageAdapter);
|
||||
}
|
||||
|
||||
private void loadLastUserMessage() {
|
||||
BmobQuery<ChatMessage_bmob> bmobQuery = new BmobQuery<>();
|
||||
bmobQuery.addWhereEqualTo("relatedBook", bookName);
|
||||
bmobQuery.addWhereEqualTo("userid", userid);
|
||||
bmobQuery.addWhereEqualTo("isuser", 1); // 只查找用户的消息
|
||||
bmobQuery.order("-createdAt"); // 按创建时间降序排列,以确保最新的消息排在最前
|
||||
bmobQuery.setLimit(1); // 只获取一条记录
|
||||
|
||||
bmobQuery.findObjects(new FindListener<ChatMessage_bmob>() {
|
||||
@Override
|
||||
public void done(List<ChatMessage_bmob> messages, BmobException e) {
|
||||
if (e == null && messages != null && !messages.isEmpty()) {
|
||||
lastUserQuestion = messages.get(0).getContent(); // 获取最新的用户消息
|
||||
// 可以在此处更新界面或处理消息
|
||||
} else {
|
||||
Log.e("ChatActivity", "No recent user message found, or error fetching data: " + (e != null ? e.getMessage() : "No details"));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void init() {
|
||||
chatbot_title.setText(bookName);
|
||||
BmobQuery<ChatMessage_bmob> bmobQuery = new BmobQuery<>();
|
||||
bmobQuery.addWhereEqualTo("relatedBook", bookName);
|
||||
@ -118,13 +188,13 @@ public class ChatWithGptActivity extends AppCompatActivity {
|
||||
// 如果没有消息,添加一条 bot 的欢迎消息
|
||||
String welcomeMessage = "你好!我是你的阅读助手。我可以帮助你解答关于书籍的各种问题,比如内容概述、作者信息、主要主题和角色分析等。请随时向我提问,现在,你有什么关于《" + bookName + "》的问题吗?";
|
||||
messageList.add(new Message(welcomeMessage, 0)); // 假设 0 表示系统或助手消息
|
||||
ChatMessage_bmob chatMessage_bmob=new ChatMessage_bmob(welcomeMessage,0,bookName,userid);
|
||||
ChatMessage_bmob chatMessage_bmob = new ChatMessage_bmob(welcomeMessage, 0, bookName, userid);
|
||||
chatMessage_bmob.save(new SaveListener<String>() {
|
||||
@Override
|
||||
public void done(String objectId,BmobException e) {
|
||||
if(e==null){
|
||||
public void done(String objectId, BmobException e) {
|
||||
if (e == null) {
|
||||
// toast("添加数据成功,返回objectId为:"+objectId);
|
||||
}else{
|
||||
} else {
|
||||
//toast("创建数据失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
@ -139,6 +209,58 @@ public class ChatWithGptActivity extends AppCompatActivity {
|
||||
});
|
||||
}
|
||||
|
||||
private void initgenerateUserQuestions() {
|
||||
BmobQuery<ChatMessage_bmob> bmobQuery = new BmobQuery<>();
|
||||
bmobQuery.addWhereEqualTo("relatedBook", bookName);
|
||||
bmobQuery.addWhereEqualTo("userid", userid);
|
||||
bmobQuery.addWhereEqualTo("isuser", 1);
|
||||
bmobQuery.findObjects(new FindListener<ChatMessage_bmob>() {
|
||||
@Override
|
||||
public void done(List<ChatMessage_bmob> messages, BmobException e) {
|
||||
if (e == null && messages != null) {
|
||||
if (!messages.isEmpty()) {
|
||||
BmobQuery<GenerateQue_bmob> bmobQueryGen = new BmobQuery<>();
|
||||
bmobQueryGen.addWhereEqualTo("relatedBook", bookName);
|
||||
bmobQueryGen.addWhereEqualTo("userid", userid);
|
||||
bmobQueryGen.findObjects(new FindListener<GenerateQue_bmob>() {
|
||||
@Override
|
||||
public void done(List<GenerateQue_bmob> list, BmobException e) {
|
||||
if (e == null) {
|
||||
for (GenerateQue_bmob generateQue : list) {
|
||||
if (generateQue.getQues1() != null) {
|
||||
questionView1.setVisibility(View.VISIBLE);
|
||||
questionView1.setText(generateQue.getQues1());
|
||||
}
|
||||
if (generateQue.getQues2() != null) {
|
||||
questionView2.setVisibility(View.VISIBLE);
|
||||
questionView2.setText(generateQue.getQues2());
|
||||
}
|
||||
if (generateQue.getQues2() != null) {
|
||||
questionView3.setVisibility(View.VISIBLE);
|
||||
questionView3.setText(generateQue.getQues3());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
questionView1.setVisibility(View.VISIBLE);
|
||||
questionView1.setText("请告诉我有关这本书的内容概述。");
|
||||
questionView2.setVisibility(View.VISIBLE);
|
||||
questionView2.setText("请告诉有关这本书作者的信息。");
|
||||
questionView3.setVisibility(View.VISIBLE);
|
||||
questionView3.setText("请告诉我这本书的主题是什么。");
|
||||
}
|
||||
messageAdapter.notifyDataSetChanged();
|
||||
} else {
|
||||
Log.e("BookInfo", "Error loading book info: " + (e != null ? e.getMessage() : ""));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 从数据库加载历史对话并构建消息列表
|
||||
*/
|
||||
@ -147,18 +269,17 @@ public class ChatWithGptActivity extends AppCompatActivity {
|
||||
BmobQuery<ChatMessage_bmob> bmobQuery = new BmobQuery<>();
|
||||
bmobQuery.addWhereEqualTo("relatedBook", bookName);
|
||||
bmobQuery.addWhereEqualTo("userid", userId);
|
||||
bmobQuery.order("createdAt");
|
||||
bmobQuery.order("-createdAt");
|
||||
bmobQuery.setLimit(10); //设置上下文最多10条历史对话
|
||||
bmobQuery.findObjects(new FindListener<ChatMessage_bmob>() {
|
||||
@Override
|
||||
public void done(List<ChatMessage_bmob> chatMessages, BmobException e) {
|
||||
if (e == null && chatMessages != null && !chatMessages.isEmpty()) {
|
||||
for (ChatMessage_bmob item : chatMessages) {
|
||||
// 根据消息来源判断角色,假设 0 表示用户,1 表示助手
|
||||
String role = item.getIsuser() == 0 ? "user" : "assistant";
|
||||
messages.add(new ChatRequest.Message(role, item.getContent()));
|
||||
Log.d("test",item.getContent());
|
||||
}
|
||||
Collections.reverse(messages); // 反转列表以使消息按时间升序排列, 展示最近的10条数据,按时间顺序。
|
||||
} else {
|
||||
Log.e("BookInfo", "Error loading book info: " + (e != null ? e.getMessage() : "No error details."));
|
||||
}
|
||||
@ -168,6 +289,7 @@ public class ChatWithGptActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void sendMessageToChatGPT(String messageText) {
|
||||
buttonSend.setImageResource(R.drawable.ic_loading);
|
||||
OkHttpClient client = new OkHttpClient.Builder()
|
||||
.connectTimeout(60, TimeUnit.SECONDS)
|
||||
.readTimeout(60, TimeUnit.SECONDS)
|
||||
@ -180,16 +302,25 @@ public class ChatWithGptActivity extends AppCompatActivity {
|
||||
.build();
|
||||
ChatGPTService service = retrofit.create(ChatGPTService.class);
|
||||
List<ChatRequest.Message> messages = new ArrayList<>();
|
||||
String prompt = "你好!我是你的阅读助手。我可以帮助你解答关于书籍的各种问题,比如内容概述、作者信息、主要主题和角色分析等。请随时向我提问,我会用中文简体来回答你。现在,你有什么关于《" + bookName + "》的问题吗?";
|
||||
messages.add(new ChatRequest.Message("system", prompt));
|
||||
String prompt = "你好!我是你的阅读助手。";
|
||||
|
||||
// messages.add(new ChatRequest.Message("system", "You are a reading assistant. The user will ask you questions about the book '" + bookName + "'."));
|
||||
if (messageText.equals("请告诉我更多内容。") && !lastUserQuestion.isEmpty()) {
|
||||
// 特别关注用户的上一个问题
|
||||
prompt += "你之前问了关于《" + bookName + "》的'" + lastUserQuestion + "'。关于这个问题,你需要更多的哪方面信息?";
|
||||
} else if (!lastUserQuestion.isEmpty()) {
|
||||
// 处理正常的用户问题
|
||||
prompt += "关于你之前的问题:" + lastUserQuestion + ",你需要我提供更多的信息吗?或者,你有其他关于《" + bookName + "》的新问题吗?";
|
||||
} else {
|
||||
// 没有历史问题的情况
|
||||
prompt += "我可以帮助你解答关于《" + bookName + "》的各种问题,比如内容概述、作者信息、主要主题和角色分析等。请随时向我提问,现在,你有什么问题吗?";
|
||||
}
|
||||
messages.add(new ChatRequest.Message("system", prompt));
|
||||
messages.addAll(loadMessagesFromDatabase(bookName, userid));
|
||||
messages.add(new ChatRequest.Message("user", messageText)); // 添加用户消息
|
||||
|
||||
ChatRequest request = new ChatRequest(messages); // 使用消息列表创建请求
|
||||
request.setModel("gpt-4-turbo"); // 根据需要选择不同的模型
|
||||
request.setMaxTokens(200); // 设置最大 token 数,根据需要调整
|
||||
request.setMaxTokens(50); // 设置最大 token 数,根据需要调整
|
||||
request.setTemperature(0.5); // 设置适当的温度
|
||||
service.postMessage(request).enqueue(new Callback<ChatResponse>() {
|
||||
@Override
|
||||
@ -201,19 +332,11 @@ public class ChatWithGptActivity extends AppCompatActivity {
|
||||
String reply = message.content; // 这是从 GPT-3.5 响应中提取的内容
|
||||
runOnUiThread(() -> {
|
||||
messageList.add(new Message(reply, 0));
|
||||
messageAdapter.notifyItemInserted(messageList.size() - 1);
|
||||
recyclerView.scrollToPosition(messageList.size() - 1);
|
||||
ChatMessage_bmob chatMessage_bmob = new ChatMessage_bmob(reply, 0, bookName, userid);
|
||||
chatMessage_bmob.save(new SaveListener<String>() {
|
||||
@Override
|
||||
public void done(String objectId, BmobException e) {
|
||||
if (e == null) {
|
||||
// toast("添加数据成功,返回objectId为:" + objectId);
|
||||
} else {
|
||||
// toast("创建数据失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
});
|
||||
messageAdapter.notifyDataSetChanged();
|
||||
moveToNewest();
|
||||
buttonSend.setImageResource(R.drawable.ic_send);
|
||||
generateUserQuestions(reply);
|
||||
storeMessage(reply,0);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
@ -226,6 +349,124 @@ public class ChatWithGptActivity extends AppCompatActivity {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<ChatResponse> call, Throwable t) {
|
||||
String content="机器人响应超时,请重新生成回答!";
|
||||
buttonSend.setImageResource(R.drawable.ic_send);
|
||||
messageList.add(new Message(content, 0));
|
||||
messageAdapter.notifyDataSetChanged();
|
||||
moveToNewest();
|
||||
storeMessage(content,0);
|
||||
Log.e("ChatGPT", "Failure: " + t.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
//自动移动至最新回答
|
||||
private void moveToNewest(){
|
||||
NestedScrollView nestedScrollView = findViewById(R.id.nestedScrollView);
|
||||
recyclerView.post(() -> {
|
||||
// 确保最后一条消息可见
|
||||
if (messageList.size() > 0) {
|
||||
recyclerView.scrollToPosition(messageList.size() - 1);
|
||||
recyclerView.post(() -> {
|
||||
// 获取最后一个视图的引用
|
||||
View lastChild = recyclerView.getChildAt(recyclerView.getChildCount() - 1);
|
||||
int bottom = lastChild.getBottom() + recyclerView.getPaddingBottom();
|
||||
int sy = nestedScrollView.getScrollY();
|
||||
int sh = nestedScrollView.getHeight();
|
||||
int delta = bottom - (sy + sh);
|
||||
nestedScrollView.smoothScrollBy(0, delta);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
//回调函数,重新生成回答
|
||||
@Override
|
||||
public void onRegenerateClick(int position) {
|
||||
questionView1.setVisibility(View.GONE);
|
||||
questionView2.setVisibility(View.GONE);
|
||||
questionView3.setVisibility(View.GONE);
|
||||
BmobQuery<ChatMessage_bmob> bmobQuery = new BmobQuery<>();
|
||||
bmobQuery.addWhereEqualTo("relatedBook", bookName);
|
||||
bmobQuery.addWhereEqualTo("userid", userid);
|
||||
bmobQuery.addWhereEqualTo("isuser", 0);
|
||||
bmobQuery.order("-createdAt");
|
||||
bmobQuery.setLimit(2);
|
||||
bmobQuery.findObjects(new FindListener<ChatMessage_bmob>() {
|
||||
@Override
|
||||
public void done(List<ChatMessage_bmob> chatMessages, BmobException e) {
|
||||
if (e == null && chatMessages != null && !chatMessages.isEmpty()) {
|
||||
for (ChatMessage_bmob item : chatMessages) {
|
||||
ChatMessage_bmob chatMessage_bmob = new ChatMessage_bmob();
|
||||
chatMessage_bmob.setObjectId(item.getObjectId());
|
||||
chatMessage_bmob.delete(new UpdateListener() {
|
||||
@Override
|
||||
public void done(BmobException e) {
|
||||
if (e == null) {
|
||||
// 删除成功
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
messageList.remove(position);
|
||||
messageAdapter.notifyItemRemoved(position);
|
||||
messageAdapter.notifyItemRangeChanged(position, messageList.size());
|
||||
sendMessageToChatGPT(lastUserQuestion);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 删除失败
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//模拟生成用户回答
|
||||
private void generateUserQuestions(String lastBotReply) {
|
||||
OkHttpClient client = new OkHttpClient.Builder()
|
||||
.connectTimeout(60, TimeUnit.SECONDS)
|
||||
.readTimeout(60, TimeUnit.SECONDS)
|
||||
.writeTimeout(60, TimeUnit.SECONDS)
|
||||
.build();
|
||||
Retrofit retrofit = new Retrofit.Builder()
|
||||
.client(client)
|
||||
.baseUrl("https://api.openai-ch.top/")
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.build();
|
||||
ChatGPTService service = retrofit.create(ChatGPTService.class);
|
||||
|
||||
// 构建请求数据
|
||||
List<ChatRequest.Message> messages = new ArrayList<>();
|
||||
messages.add(new ChatRequest.Message("system", "请你模拟用户的口吻,基于《" + bookName + "》" +
|
||||
"的内容,请根据上一条聊天机器人的回复,生成两个读者可能的简短提问,每个提问不多于20个字,每个问题占一行,以序号开头,示例如下:1.勒庞是否提出了群体心理中的自我意识丧失和传染性特征?" +
|
||||
"2.《乌合之众》是否强调了群体行为易受领导者情感诉求的影响?"));
|
||||
messages.add(new ChatRequest.Message("user", lastBotReply)); // 模拟用户的提问
|
||||
|
||||
ChatRequest request = new ChatRequest(messages);
|
||||
request.setModel("gpt-3.5-turbo");
|
||||
request.setMaxTokens(60); // 增加 token 数以生成多个问题
|
||||
request.setTemperature(0.9); // 较高温度以增加多样性
|
||||
|
||||
service.postMessage(request).enqueue(new Callback<ChatResponse>() {
|
||||
@Override
|
||||
public void onResponse(Call<ChatResponse> call, Response<ChatResponse> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
ChatResponse chatResponse = response.body();
|
||||
List<String> questions = extractQuestions(chatResponse);
|
||||
runOnUiThread(() -> displayQuestions(questions));
|
||||
} else {
|
||||
try {
|
||||
String errorBody = response.errorBody() != null ? response.errorBody().string() : "Unknown error";
|
||||
Log.e("ChatGPT", "Error: " + errorBody);
|
||||
} catch (IOException e) {
|
||||
Log.e("ChatGPT", "Error reading error body", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<ChatResponse> call, Throwable t) {
|
||||
Log.e("ChatGPT", "Failure: " + t.getMessage());
|
||||
@ -233,5 +474,88 @@ public class ChatWithGptActivity extends AppCompatActivity {
|
||||
});
|
||||
}
|
||||
|
||||
// 提取问题
|
||||
private List<String> extractQuestions(ChatResponse response) {
|
||||
GenerateQue_bmob generateQue_bmob = new GenerateQue_bmob();
|
||||
generateQue_bmob.setQues1("请告诉我更多。");
|
||||
generateQue_bmob.setUserid(userid);
|
||||
generateQue_bmob.setRelatedBook(bookName);
|
||||
List<String> questions = new ArrayList<>();
|
||||
|
||||
if (response.getChoices() != null && !response.getChoices().isEmpty()) {
|
||||
String text = response.choices.get(0).message.content;
|
||||
if (text != null && !text.trim().isEmpty()) {
|
||||
Log.d("ChatGPT Response:", text);
|
||||
String[] lines = text.trim().split("\\r?\\n");
|
||||
int questionIndex = 2; // Start from ques2 since ques1 is set by default
|
||||
|
||||
for (String line : lines) {
|
||||
if (line.matches("^\\d+\\.\\s+.*")) {
|
||||
String cleanedLine = line.replaceFirst("^\\d+\\.\\s*", "");
|
||||
if (!cleanedLine.trim().isEmpty()) {
|
||||
questions.add(cleanedLine);
|
||||
// Set questions to Bmob object based on availability
|
||||
if (questionIndex == 2) {
|
||||
generateQue_bmob.setQues2(cleanedLine);
|
||||
questionIndex++;
|
||||
} else if (questionIndex == 3) {
|
||||
generateQue_bmob.setQues3(cleanedLine);
|
||||
questionIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BmobQuery<GenerateQue_bmob> bmobQuery = new BmobQuery<>();
|
||||
bmobQuery.addWhereEqualTo("relatedBook", bookName);
|
||||
bmobQuery.addWhereEqualTo("userid", userid);
|
||||
bmobQuery.findObjects(new FindListener<GenerateQue_bmob>() {
|
||||
@Override
|
||||
public void done(List<GenerateQue_bmob> list, BmobException e) {
|
||||
if (e == null && !list.isEmpty()) {
|
||||
generateQue_bmob.update(list.get(0).getObjectId(), new UpdateListener() {
|
||||
@Override
|
||||
public void done(BmobException e) {
|
||||
if (e == null) {
|
||||
//toast("更新成功:"+p2.getUpdatedAt());
|
||||
} else {
|
||||
//toast("更新失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Save the Bmob object to database
|
||||
generateQue_bmob.save(new SaveListener<String>() {
|
||||
@Override
|
||||
public void done(String objectId, BmobException e) {
|
||||
if (e == null) {
|
||||
Log.d("Save Successful", "Object saved with objectId: " + objectId);
|
||||
} else {
|
||||
Log.e("Save Failed", "Error saving object: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return questions;
|
||||
}
|
||||
|
||||
|
||||
// 将问题显示在 UI 上的逻辑
|
||||
private void displayQuestions(List<String> questions) {
|
||||
questionView1.setText("请告诉我更多内容。");
|
||||
questionView1.setVisibility(View.VISIBLE);
|
||||
|
||||
// Display questions based on size
|
||||
if (questions.size() > 0) {
|
||||
questionView2.setText(questions.get(0));
|
||||
questionView2.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (questions.size() > 1) {
|
||||
questionView3.setText(questions.get(1));
|
||||
questionView3.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
BIN
hwtxtreaderlib/src/main/res/drawable/ic_loading.png
Normal file
BIN
hwtxtreaderlib/src/main/res/drawable/ic_loading.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 965 B |
BIN
hwtxtreaderlib/src/main/res/drawable/ic_return.png
Normal file
BIN
hwtxtreaderlib/src/main/res/drawable/ic_return.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
BIN
hwtxtreaderlib/src/main/res/drawable/ic_send.png
Normal file
BIN
hwtxtreaderlib/src/main/res/drawable/ic_send.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 687 B |
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@android:color/white" />
|
||||
<corners android:radius="8dp" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="@android:color/black" />
|
||||
</shape>
|
@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
@ -6,52 +5,122 @@
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".ui.ChatWithGptActivity">
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/nestedScrollView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/inputEditText"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/chatbot_title">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- RecyclerView 聊天区域 -->
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/chatRecyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<!-- Question Container -->
|
||||
<LinearLayout
|
||||
android:id="@+id/questionContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/question1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:background="@drawable/rounded_question_background"
|
||||
android:padding="4dp"
|
||||
android:text="请告诉我更多。"
|
||||
android:textColor="@android:color/black"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/question2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:background="@drawable/rounded_question_background"
|
||||
android:padding="4dp"
|
||||
android:text="testtesttesttesttesttest"
|
||||
android:textColor="@android:color/black"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/question3"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:background="@drawable/rounded_question_background"
|
||||
android:padding="4dp"
|
||||
android:text="testtesttesttesttesttest"
|
||||
android:textColor="@android:color/black"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/chat_return"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:src="@drawable/ic_return"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/chatbot_title"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="@id/chatbot_title" />
|
||||
|
||||
<!-- 标题栏 -->
|
||||
<TextView
|
||||
android:id="@+id/chatbot_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="书名"
|
||||
android:textSize="20sp"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="16dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"/>
|
||||
|
||||
<!-- RecyclerView 聊天区域 -->
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/chatRecyclerView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="8dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/chatbot_title"
|
||||
app:layout_constraintBottom_toTopOf="@id/inputEditText"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"/>
|
||||
android:text="书名"
|
||||
android:textSize="22sp"
|
||||
android:gravity="center"
|
||||
app:layout_constraintStart_toEndOf="@id/chat_return"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<!-- 输入框 -->
|
||||
<EditText
|
||||
android:id="@+id/inputEditText"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:hint="输入消息..."
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toLeftOf="@id/sendButton"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="8dp" />
|
||||
app:layout_constraintRight_toLeftOf="@id/sendButton" />
|
||||
|
||||
<!-- 发送按钮 -->
|
||||
<Button
|
||||
<ImageView
|
||||
android:id="@+id/sendButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="发送"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:src="@drawable/ic_send"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:layout_marginRight="16dp" />
|
||||
|
||||
app:layout_constraintRight_toRightOf="parent"></ImageView>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
@ -29,7 +29,6 @@
|
||||
android:src="@drawable/ic_copy"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:alpha="0.6"
|
||||
android:visibility="gone"
|
||||
android:contentDescription="Copy text" />
|
||||
|
||||
<ImageView
|
||||
@ -39,7 +38,6 @@
|
||||
android:src="@drawable/ic_regenerate"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:alpha="0.6"
|
||||
android:visibility="gone"
|
||||
android:contentDescription="Regenerate response" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
Loading…
x
Reference in New Issue
Block a user