【Android】Jetpack全组件实战开发短视频应用App(十八)

【Android】Jetpack全组件实战开发短视频应用App(十八),第1张

概述前言上一篇我们已经写完图文详情的布局展示,这一篇我们将完成图文详情的数据展示实现因为我们这个详情分为图文和视频,所以我们采用组合方式实现,相同的部分我们提取自父类中去完成我们跳转到详情需要这个帖子的相关信息,所以我们需要传过来一个Feed对象 Feedfeed=(F 前言

上一篇我们已经写完图文详情的布局展示,这一篇我们将完成图文详情的数据展示

实现

因为我们这个详情分为图文和视频,所以我们采用组合方式实现,相同的部分我们提取自父类中去完成

我们跳转到详情需要这个帖子的相关信息,所以我们需要传过来一个Feed对象

		 Feed Feed = (Feed) getIntent().getSerializableExtra(KEY_Feed);        if (Feed == null) {            finish();            return;        }

然后我们根据帖子ItemType来区分

  if (Feed.itemType == Feed.TYPE_IMAGE_TEXT) {            vIEwHandler = new ImageVIEwHandler(this);        } else {            vIEwHandler = new VIDeoVIEwHandler(this);        }

这个的这个vIEwHandlerVIEwHandler这个类,这个类是处理相同逻辑部分的,它对应的就是两个子类ImageVIEwHandlerVIDeoVIEwHandler,接着我们就通过bindInitData方法对VIEwHandler设置,所以我们详情页的onCreate方法如下

 @OverrIDe    protected voID onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Feed Feed = (Feed) getIntent().getSerializableExtra(KEY_Feed);        if (Feed == null) {            finish();            return;        }        if (Feed.itemType == Feed.TYPE_IMAGE_TEXT) {            vIEwHandler = new ImageVIEwHandler(this);        } else {            vIEwHandler = new VIDeoVIEwHandler(this);        }        vIEwHandler.bindInitData(Feed);    }

然后我们回到VIEwHandler这个类中,这个类我们需要做列表数据绑定,底部互动绑定以及行为处理,所以这个类里面需要有RecyclerVIEw对象和底部DataBinding对象,并且我们在我们的bindInitData方法中初始化一下

  protected FragmentActivity mActivity;    protected Feed mFeed;    protected RecyclerVIEw mRecyclerVIEw;    protected LayoutFeedDetailBottomInateractionBinding mInateractionBinding;    protected FeedCommentAdapter mlistadapter;    public VIEwHandler(FragmentActivity activity) {        mActivity = activity;;    }    @CallSuper    public voID bindInitData(Feed Feed) {        mInateractionBinding.setowner(mActivity);        mFeed = Feed;        mRecyclerVIEw.setLayoutManager(new linearlayoutmanager(mActivity, linearlayoutmanager.VERTICAL, false));        mRecyclerVIEw.setItemAnimator(null);        mlistadapter = new FeedCommentAdapter(mActivity);        mRecyclerVIEw.setAdapter(mlistadapter);    }

这里我们需要这个列表写一个适配器FeedCommentAdapter,列表大概样式如下

<?xml version="1.0" enCoding="utf-8"?><layout 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">    <data>        <variable            name="comment"            type="com.mooc.ppjoke.model.Comment" />        <import type="androID.text.TextUtils"/>        <import type="androID.vIEw.VIEw"/>        <import type="com.mooc.ppjoke.ui.login.UserManager"/>        <import type="com.mooc.ppjoke.utils.TimeUtils"/>        <import type="com.mooc.ppjoke.ui.InteractionPresenter"/>        <variable            name="owner"            type="androIDx.lifecycle.lifecycleOwner" />    </data>    <androIDx.constraintlayout.Widget.ConstraintLayout        androID:layout_wIDth="match_parent"        androID:layout_height="wrap_content"        androID:orIEntation="vertical"        androID:paddingBottom="@dimen/dp_10">        <com.mooc.libcommon.vIEw.PPImageVIEw            androID:ID="@+ID/author_avatar"            androID:layout_wIDth="@dimen/dp_40"            androID:layout_height="@dimen/dp_40"            androID:layout_marginleft="@dimen/dp_16"            androID:layout_margintop="@dimen/dp_16"            app:image_url="@{comment.author.avatar}"            app:isCircle="@{true}"            app:layout_constraintleft_toleftOf="parent"            app:layout_constrainttop_totopOf="parent"            tools:src="@drawable/splash"/>        <TextVIEw            androID:ID="@+ID/author_name"            androID:layout_wIDth="wrap_content"            androID:layout_height="wrap_content"            androID:layout_marginleft="@dimen/dp_10"            androID:layout_margintop="@dimen/dp_16"            androID:text="@{comment.author.name}"            androID:textcolor="@color/color_000"            androID:textSize="@dimen/sp_12"            app:layout_constraintleft_toRightOf="@+ID/author_avatar"            app:layout_constrainttop_totopOf="parent"            tools:text="神秘的jetpack"/>        <com.Google.androID.material.button.Materialbutton            androID:ID="@+ID/label_author"            androID:layout_wIDth="wrap_content"            androID:layout_height="@dimen/dp_14"            androID:layout_marginleft="@dimen/dp_10"            androID:layout_margintop="@dimen/dp_16"            androID:gravity="center"            androID:includeFontpadding="false"            androID:paddingleft="@dimen/dp_5"            androID:paddingtop="@dimen/dp_0"            androID:paddingRight="@dimen/dp_5"            androID:paddingBottom="@dimen/dp_0"            androID:stateListAnimator="@null"            androID:text="@string/author"            androID:textcolor="@color/color_white"            androID:textSize="10sp"            app:backgroundTint="@color/color_theme"            app:cornerRadius="@dimen/dp_3"            app:layout_constraintBaseline_toBaselineOf="@+ID/author_name"            app:layout_constraintleft_toRightOf="@+ID/author_name"            app:layout_constrainttop_totopOf="parent"/>        <TextVIEw            androID:ID="@+ID/create_time"            androID:layout_wIDth="wrap_content"            androID:layout_height="wrap_content"            androID:layout_marginleft="@dimen/dp_10"            androID:layout_margintop="@dimen/dp_16"            androID:text="@{TimeUtils.calculate(comment.createTime)}"            androID:textcolor="@color/color_999"            androID:textSize="10sp"            app:layout_constraintBaseline_toBaselineOf="@+ID/author_name"            app:layout_constraintleft_toRightOf="@+ID/label_author"            app:layout_constrainttop_totopOf="parent"            tools:text="12天前"/>        <TextVIEw            androID:ID="@+ID/comment_like"            androID:layout_wIDth="wrap_content"            androID:layout_height="wrap_content"            androID:layout_margintop="@dimen/dp_16"            androID:layout_marginRight="16dp"            androID:drawableRight="@{comment.ugc.hasliked?@drawable/icon_cell_liked:@drawable/icon_cell_like}"            androID:drawablepadding="@dimen/dp_3"            androID:gravity="center_vertical"            androID:includeFontpadding="false"            androID:onClick="@{()->InteractionPresenter.toggleCommentlike(owner,comment)}"            androID:text="@{String.valueOf(comment.ugc.likeCount)}"            androID:textcolor="@{comment.ugc.hasliked?@color/color_theme:@color/color_999}"            androID:textSize="@dimen/sp_10"            app:layout_constraintRight_toRightOf="parent"            app:layout_constrainttop_totopOf="parent"            tools:drawableRight="@drawable/icon_cell_liked_large"            tools:text="1000"/>        <ImageVIEw            androID:ID="@+ID/comment_delete"            androID:layout_wIDth="@dimen/dp_14"            androID:layout_height="@dimen/dp_14"            androID:layout_marginRight="@dimen/dp_10"            androID:src="@drawable/icon_item_cell_delete"            app:layout_constraintBottom_toBottomOf="@ID/comment_like"            app:layout_constraintRight_toleftOf="@+ID/comment_like"            app:layout_constrainttop_totopOf="@ID/comment_like"/>        <TextVIEw            androID:ID="@+ID/comment_text"            androID:layout_wIDth="0dp"            androID:layout_height="wrap_content"            androID:layout_marginleft="@dimen/dp_10"            androID:layout_margintop="@dimen/dp_5"            androID:gravity="center_vertical"            androID:includeFontpadding="false"            androID:text="@{comment.commentText}"            androID:textcolor="@color/color_333"            androID:textSize="@dimen/sp_14"            app:layout_constraintHorizontal_weight="1"            app:layout_constraintleft_toRightOf="@+ID/author_avatar"            app:layout_constraintRight_toleftOf="@+ID/comment_like"            app:layout_constrainttop_toBottomOf="@+ID/author_name"            tools:text="comment.commentText"/>        <FrameLayout            androID:ID="@+ID/comment_ext"            androID:layout_wIDth="wrap_content"            androID:layout_height="wrap_content"            androID:layout_marginleft="@dimen/dp_10"            androID:layout_margintop="@dimen/dp_10"            app:layout_constraintleft_toRightOf="@+ID/author_avatar"            app:layout_constrainttop_toBottomOf="@ID/comment_text">            <com.mooc.libcommon.vIEw.PPImageVIEw                androID:ID="@+ID/comment_cover"                androID:layout_wIDth="wrap_content"                androID:layout_height="wrap_content"                androID:layout_gravity="center"                androID:background="@color/color_gray2"                androID:scaleType="center"                tools:layout_height="100dp"                tools:layout_wIDth="100dp">            </com.mooc.libcommon.vIEw.PPImageVIEw>            <ImageVIEw                androID:ID="@+ID/vIDeo_icon"                androID:layout_wIDth="@dimen/dp_25"                androID:layout_height="@dimen/dp_25"                androID:layout_gravity="center"                androID:src="@drawable/icon_vIDeo_play"/>        </FrameLayout>    </androIDx.constraintlayout.Widget.ConstraintLayout></layout>

然后我们写这个适配器的Java代码

public class FeedCommentAdapter extends AbsPagedlistadapter<Comment, FeedCommentAdapter.VIEwHolder> {    private LayoutInflater mInflater;    private Context mContext;    protected FeedCommentAdapter(Context context) {        super(new DiffUtil.ItemCallback<Comment>() {            @OverrIDe            public boolean areItemsTheSame(@NonNull Comment oldItem, @NonNull Comment newItem) {                return oldItem.ID == newItem.ID;            }            @OverrIDe            public boolean areContentsTheSame(@NonNull Comment oldItem, @NonNull Comment newItem) {                return oldItem.equals(newItem);            }        });        mContext = context;        mInflater = LayoutInflater.from(context);    }    @OverrIDe    protected VIEwHolder onCreateVIEwHolder2(VIEwGroup parent, int vIEwType) {        LayoutFeedCommentListItembinding binding = LayoutFeedCommentListItembinding.inflate(mInflater, parent, false);        return new VIEwHolder(binding.getRoot(), binding);    }    @OverrIDe    protected voID onBindVIEwHolder2(VIEwHolder holder, int position) {        Comment item = getItem(position);        holder.bindData(item);            }    public class VIEwHolder extends RecyclerVIEw.VIEwHolder {        private LayoutFeedCommentListItembinding mBinding;        public VIEwHolder(@NonNull VIEw itemVIEw, LayoutFeedCommentListItembinding binding) {            super(itemVIEw);            mBinding = binding;        }        public voID bindData(Comment item) {            mBinding.setComment(item);            boolean self = item.author != null && UserManager.get().getUserID() == item.author.userID;            mBinding.labelAuthor.setVisibility(self ? VIEw.VISIBLE : VIEw.GONE);            mBinding.commentDelete.setVisibility(self ? VIEw.VISIBLE : VIEw.GONE);            if (!TextUtils.isEmpty(item.imageUrl)) {                mBinding.commentExt.setVisibility(VIEw.VISIBLE);                mBinding.commentCover.setVisibility(VIEw.VISIBLE);                mBinding.commentCover.bindData(item.wIDth, item.height, 0, PixUtils.dp2px(200), PixUtils.dp2px(200), item.imageUrl);                if (!TextUtils.isEmpty(item.vIDeoUrl)) {                    mBinding.vIDeoIcon.setVisibility(VIEw.VISIBLE);                } else {                    mBinding.vIDeoIcon.setVisibility(VIEw.GONE);                }            } else {                mBinding.commentCover.setVisibility(VIEw.GONE);                mBinding.vIDeoIcon.setVisibility(VIEw.GONE);                mBinding.commentExt.setVisibility(VIEw.GONE);            }        }    }}

我们写完评论列表之后,先完成图文详情页的头部数据绑定,并且给这个RecyclerVIEw添加这个头部,我们回到ImageVIEwHandler这个类,这里有两个DataBinding,一个是图文详情的,我们通过这个拿到列表和底部互动布局,一个是头部的

public class ImageVIEwHandler extends VIEwHandler {    protected ActivityFeedDetailTypeImageBinding mImageBinding;    protected LayoutFeedDetailTypeImageheaderBinding mheaderBinding;    public ImageVIEwHandler(FragmentActivity activity) {        super(activity);        mImageBinding = DataBindingUtil.setContentVIEw(activity, R.layout.activity_Feed_detail_type_image);        mInateractionBinding = mImageBinding.interactionLayout;        mRecyclerVIEw = mImageBinding.recyclerVIEw;    }    @OverrIDe    public voID bindInitData(Feed Feed) {        super.bindInitData(Feed);        mImageBinding.setFeed(mFeed);        mheaderBinding = LayoutFeedDetailTypeImageheaderBinding.inflate(LayoutInflater.from(mActivity), mRecyclerVIEw, false);        mheaderBinding.setFeed(mFeed);        PPImageVIEw headerImage = mheaderBinding.headerImage;        headerImage.bindData(mFeed.wIDth, mFeed.height, mFeed.wIDth > mFeed.height ? 0 : 16, mFeed.cover);        mlistadapter.addheaderVIEw(mheaderBinding.getRoot());        mRecyclerVIEw.addOnScrollListener(new RecyclerVIEw.OnScrollListener() {            @OverrIDe            public voID onScrolled(@NonNull RecyclerVIEw recyclerVIEw, int dx, int dy) {                super.onScrolled(recyclerVIEw, dx, dy);                boolean visible = mheaderBinding.getRoot().gettop() <= -mImageBinding.TitleLayout.getMeasuredHeight();                mImageBinding.authorInfolayout.getRoot().setVisibility(visible ? VIEw.VISIBLE : VIEw.GONE);                mImageBinding.Title.setVisibility(visible ? VIEw.GONE : VIEw.VISIBLE);            }        });    }}

这里我们是监听列表的滑动,滑动一定的距离后我们就需要改变UI样式

OK,接着我们就可以写网络请求了,首先是获取评论列表,我们新建一个viewmodel,在这个类里面做数据请求

public class FeedDetailviewmodel extends Absviewmodel<Comment> {    private long itemID;    @OverrIDe    public DataSource createDataSource() {        return new DataSource();    }    public voID setItemID(long itemID) {        this.itemID = itemID;    }    class DataSource extends ItemKeyedDataSource<Integer, Comment> {        @OverrIDe        public voID loadInitial(@NonNull LoadInitialParams<Integer> params, @NonNull LoadInitialCallback<Comment> callback) {            loadData(params.requestedInitialKey, params.requestedLoadSize, callback);        }        @OverrIDe        public voID loadAfter(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Comment> callback) {            if (params.key > 0) {                loadData(params.key, params.requestedLoadSize, callback);            }        }        private voID loadData(Integer key, int requestedLoadSize, LoadCallback<Comment> callback) {            APIResponse<List<Comment>> response = APIService.get("/comment/queryFeedComments")                    .addParam("ID", key)                    .addParam("itemID", itemID)                    .addParam("userID", UserManager.get().getUserID())                    .addParam("pageCount", requestedLoadSize)                    .responseType(new TypeReference<ArrayList<Comment>>() {                    }.getType())                    .execute();            List<Comment> List = response.body == null ? Collections.emptyList() : response.body;            callback.onResult(List);        }        @OverrIDe        public voID loadBefore(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Comment> callback) {            callback.onResult(Collections.emptyList());        }        @NonNull        @OverrIDe        public Integer getKey(@NonNull Comment item) {            return item.ID;        }    }}

然后我们回到VIEwHandler中触发加载逻辑
首先通过viewmodelProvIDers拿到我们的viewmodel对象

  public VIEwHandler(FragmentActivity activity) {        mActivity = activity;        viewmodel = viewmodelProvIDers.of(activity).get(FeedDetailviewmodel.class);    }

接着就是在bindInitData触发

 viewmodel.setItemID(mFeed.itemID);        viewmodel.getPageData().observe(mActivity, new Observer<PagedList<Comment>>() {            @OverrIDe            public voID onChanged(PagedList<Comment> comments) {                mlistadapter.submitList(comments);                handleEmpty(comments.size() > 0);            }        });
 private EmptyVIEw mEmptyVIEw;    public voID handleEmpty(boolean hasData) {        if (hasData) {            if (mEmptyVIEw != null) {                mlistadapter.removeheaderVIEw(mEmptyVIEw);            }        } else {            if (mEmptyVIEw == null) {                mEmptyVIEw = new EmptyVIEw(mActivity);                RecyclerVIEw.LayoutParams layoutParams = new RecyclerVIEw.LayoutParams(VIEwGroup.LayoutParams.MATCH_PARENT, VIEwGroup.LayoutParams.WRAP_CONTENT);                layoutParams.topmargin = PixUtils.dp2px(40);                mEmptyVIEw.setLayoutParams(layoutParams);                mEmptyVIEw.setTitle(mActivity.getString(R.string.Feed_comment_empty));            }            mlistadapter.addheaderVIEw(mEmptyVIEw);        }    }

然后我们就要写底部互动区域的行为事件了,我们先看下都有哪些

点赞和分享我们之前写过了,我们主要就是写收藏和关注以及删除,我们还是在InteractionPresenter这个类中完成

  //收藏/取消收藏一个帖子    public static voID toggleFeedFavorite(lifecycleOwner owner, Feed Feed) {        if (!isLogin(owner, new Observer<User>() {            @OverrIDe            public voID onChanged(User user) {                toggleFeedFavorite(Feed);            }        })) {        } else {            toggleFeedFavorite(Feed);        }    }    private static voID toggleFeedFavorite(Feed Feed) {        APIService.get("/ugc/toggleFavorite")                .addParam("itemID", Feed.itemID)                .addParam("userID", UserManager.get().getUserID())                .execute(new JsonCallback<JsONObject>() {                    @OverrIDe                    public voID onSuccess(APIResponse<JsONObject> response) {                        if (response.body != null) {                            boolean hasFavorite = response.body.getBooleanValue("hasFavorite");                            Feed.getUgc().setHasFavorite(hasFavorite);                        }                    }                    @OverrIDe                    public voID one rror(APIResponse<JsONObject> response) {                        showToast(response.message);                    }                });    }    //关注/取消关注一个用户    public static voID toggleFollowUser(lifecycleOwner owner, Feed Feed) {        if (!isLogin(owner, new Observer<User>() {            @OverrIDe            public voID onChanged(User user) {                toggleFollowUser(Feed);            }        })) {        } else {            toggleFollowUser(Feed);        }    }    private static voID toggleFollowUser(Feed Feed) {        APIService.get("/ugc/toggleUserFollow")                .addParam("followUserID", UserManager.get().getUserID())                .addParam("userID", Feed.author.userID)                .execute(new JsonCallback<JsONObject>() {                    @OverrIDe                    public voID onSuccess(APIResponse<JsONObject> response) {                        if (response.body != null) {                            boolean hasFollow = response.body.getBooleanValue("hasliked");                            Feed.getAuthor().setHasFollow(hasFollow);                        }                    }                    @OverrIDe                    public voID one rror(APIResponse<JsONObject> response) {                        showToast(response.message);                    }                });    }

这里主要实现和之前差不多,就不说明了,然后我们在对应的xml中添加上点击事件即可,做完这些之后我们把帖子列表的Item点击事件加上FeedAdapter

  @OverrIDe    protected voID onBindVIEwHolder2(VIEwHolder holder, int position) {        final Feed Feed = getItem(position);        holder.bindData(Feed);        holder.itemVIEw.setonClickListener(new VIEw.OnClickListener() {            @OverrIDe            public voID onClick(VIEw v) {                FeedDetailActivity.startFeedDetailActivity(mContext, Feed, mcategory);            }        });    }

我们给我们的详情页添加一个跳转方法

 private static final String KEY_Feed = "key_Feed";    public static final String KEY_category = "key_category";    public static voID startFeedDetailActivity(Context context, Feed item, String category) {        Intent intent = new Intent(context, FeedDetailActivity.class);        intent.putExtra(KEY_Feed, item);        intent.putExtra(KEY_category, category);        context.startActivity(intent);    }

OK,然后我们运行下看看效果

总结

以上是内存溢出为你收集整理的【Android】Jetpack全组件实战开发短视频应用App(十八)全部内容,希望文章能够帮你解决【Android】Jetpack全组件实战开发短视频应用App(十八)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1060893.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-25
下一篇2022-05-25

发表评论

登录后才能评论

评论列表(0条)

    保存