第一轮铁大树洞APP开发冲刺(4)
写在前面
今天主要实现了看帖和回帖功能。这个功能是昨晚十点多构思好的,结果越写思路越不明朗,多类型的适配器怎么也写不好。撑到十二点多顶不住了,干脆睡觉。在床上理了一遍思路后,早上起来上完课不用半小时就写完了功能。这倒是也告诉我写代码的时候一定要先想好再下手,尤其是做项目的时候。很有可能改一个功能会影响整体框架。现在我们的项目代码量也有两三千了,我负责写的模块少说也有一千(大部分是逻辑层)。如果我自己理不清的话,很容易出BUG。所以在吸取教训的基础上,下午继续做回帖功能。写代码倒是很顺畅,但最后却出现了不明BUG。最后也是不明所以的解决了。今天的团队冲刺博客:
https://www.cnblogs.com/three3/p/12740291.html 今天已经是团队冲刺第四天了。明天歇一下,理一下整体的逻辑思路。以防最后会出现致命性BUG。
功能截图
今天主要是实现了看帖和回帖,如图:
在评论区的最底下有评论功能,输入内容后点击回复即可回复帖子。
看帖功能实现逻辑
首先是看帖功能,这里用到了一个多条目类型的RecyclerView.实现的逻辑和普通的RecyclerView其实差不多,我们首先定义一个类存储每个条目的内容:
public class PostAndRepost {
private int type;
private ItemBean post;
private ItemBeanRepost reposts;
}
其中ItemBeanRepost的代码如下:
public class ItemBeanRepost {
private String name;
private String content;
private String posttime;
}
之后最关键的,我们要设置适配器:
package com.androidlearing.tdtreehole.adapter;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.androidlearing.tdtreehole.R;
import com.androidlearing.tdtreehole.pojo.Post;
import com.androidlearing.tdtreehole.pojo.PostAndRepost;
import com.androidlearing.tdtreehole.pojo.Repost;
import org.w3c.dom.Text;
import java.util.List;
/**
* @ProjectName: TDTreeHole
* @Package: com.androidlearing.tdtreehole.adapter
* @ClassName: PostAndRepostAdapter
* @Description: 看帖模块的适配器
* @Author: 武神酱丶
* @CreateDate: 2020/4/19 23:02
* @UpdateUser: 更新者
* @UpdateDate: 2020/4/19 23:02
* @UpdateRemark: 更新说明
* @Version: 1.0
*/
public class PostAndRepostAdapter extends RecyclerView.Adapter {
private static final String TAG = "PostAndRepostAdapter";
//定义两个List变量
private final List<PostAndRepost> mData;
//定义两个常量标识,因为有两种类型
public static final int TYPE_POST_CONTENT = 0;
public static final int TYPE_REPOST_CONTENT = 1;
//使用构造方法获得数据
public PostAndRepostAdapter(List<PostAndRepost> data){
this.mData = data;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//这里去创建ViewHolder
View view;
if(viewType == TYPE_POST_CONTENT){
view = View.inflate(parent.getContext(), R.layout.item_repost_postcontent,null);
return new PostContentViewHolder(view);
}else{
view = View.inflate(parent.getContext(),R.layout.item_repost_repostcontent,null);
return new RepostContentViewHolder(view);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
//根据条目类型绑定数据
if(holder instanceof PostContentViewHolder){
PostContentViewHolder postContentViewHolder = (PostContentViewHolder) holder;
postContentViewHolder.mUsername.setText(mData.get(position).getPost().getUsername());
postContentViewHolder.mPostContent.setText(mData.get(position).getPost().getContent());
postContentViewHolder.mPostTime.setText(mData.get(position).getPost().getPosttime());
}else if(holder instanceof RepostContentViewHolder){
RepostContentViewHolder viewHolder = (RepostContentViewHolder) holder;
viewHolder.mRepostUsername.setText(mData.get(position).getReposts().getName());
viewHolder.mRepostTime.setText(mData.get(position).getReposts().getPosttime());
viewHolder.mRepostContent.setText(mData.get(position).getReposts().getContent());
}
}
//这里返回条目数量
@Override
public int getItemCount() {
return mData.size();
}
//复写该方法来根据条件取得条目种类
@Override
public int getItemViewType(int position) {
PostAndRepost postAndRepost = mData.get(position);
if(postAndRepost.getType() ==TYPE_POST_CONTENT){
return TYPE_POST_CONTENT;
}else{
return TYPE_REPOST_CONTENT;
}
}
private class PostContentViewHolder extends RecyclerView.ViewHolder {
private final TextView mUsername;
private final TextView mPostContent;
private final TextView mPostTime;
public PostContentViewHolder(View view) {
super(view);
//找到控件
mUsername = view.findViewById(R.id.user_name_tv);
mPostTime = view.findViewById(R.id.post_time_tv);
mPostContent = view.findViewById(R.id.post_content_tv);
}
}
private class RepostContentViewHolder extends RecyclerView.ViewHolder {
private final TextView mRepostUsername;
private final TextView mRepostTime;
private final TextView mRepostContent;
public RepostContentViewHolder(View view) {
super(view);
//找到控件
mRepostUsername = view.findViewById(R.id.repost_user_name_tv);
mRepostTime = view.findViewById(R.id.reposts_content_time_tv);
mRepostContent = view.findViewById(R.id.reposts_content_tv);
}
}
}
这里的关键是要复写GetItemType方法来取得我们自己的item类型,然后根据不同item类型设置view和InnerHolder即可。
在设置好适配器后,剩下的就简单了。我们通过Intent传递帖子的ID等信息到看帖Activity,然后在其中读取该帖子对应的回帖信息,最后把所有帖子展示出来。
回帖功能实现逻辑
要实现回帖功能,首先要有layout布局。这里查阅了资料后发现可以用为RecyclerView添加footview的方式来实现。但原生的控件并不包含此功能。因此使用了封装了该功能的xRecyclerView来进行实现。其中还包含了下拉加载,上拉刷新等等功能的封装。添加好布局后我们实现点击事件即可(这里遇到了十分狗血的BUG,我的按钮点击事件死活没法触发。烦恼了我N久,最后通过换了一种方式实现了,但EditText又无法被监听了。把代码给队友看了看后暂且解决了这个问题。这里可能是焦点重叠的问题。)。具体代码如下:
public void TestRepost(View view){
Log.d(TAG,"onClick...");
mContent = mRepostContent.getText().toString();
int postid = mPostForSelf.getPostid();
Log.d(TAG,"content =="+mContent);
//设置日期格式
DateFormat dateFormat = DateFormat.getDateInstance(2);
//获取当前时间
String publishtime =dateFormat.format(new Date());
//简单的判空处理
if (TextUtils.isEmpty(mContent)) {
Toast.makeText(RepostActivity.this,"请输入回复内容!",Toast.LENGTH_SHORT).show();
return;
}
final Repost repost = new Repost();
repost.setPostid(postid);
repost.setContent(mContent);
repost.setPublishtime(publishtime);
//暂时使用测试数据,等登录注册模块做好后Intent传值过来
repost.setUserid(1);
//去插入数据
insertRepost(repost);
}
其中取数据和插入数据的代码就不再放了,不然博客也太长了。
总结
今天的这次写代码学到了很多东西,比如写代码前一定要理好思路,比如遇到BUG时不要一直拼命解决,适时的休息也是必要的。总之,冲刺学到了很多。加油奥利给!