第一轮铁大树洞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时不要一直拼命解决,适时的休息也是必要的。总之,冲刺学到了很多。加油奥利给!

猜你喜欢

转载自www.cnblogs.com/wushenjiang/p/12741016.html