
上一篇我们已经写完图文详情的布局展示,这一篇我们将完成图文详情的数据展示
实现因为我们这个详情分为图文和视频,所以我们采用组合方式实现,相同的部分我们提取自父类中去完成
我们跳转到详情需要这个帖子的相关信息,所以我们需要传过来一个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); }这个的这个vIEwHandler是VIEwHandler这个类,这个类是处理相同逻辑部分的,它对应的就是两个子类ImageVIEwHandler和VIDeoVIEwHandler,接着我们就通过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(十八)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)