Example Implementation on Video Feed
Let's consider an example, on Video Feed Theme, where you want to add a CTA button for redirection to different above the link icon like this, using views and logic provided by LikeMinds Feed SDK.
Create Custom Layout
To display the above layout, Create an xml
file in layout
folder as item_custom_video_theme_view.xml
<?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="position"
type="int" />
<variable
name="postViewData"
type="com.likeminds.feed.android.core.socialfeed.model.LMFeedPostViewData" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.likeminds.feed.android.core.ui.widgets.post.postmedia.view.LMFeedPostVerticalVideoMediaView
android:id="@+id/post_video_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<com.likeminds.feed.android.core.ui.widgets.post.postheaderview.view.LMFeedPostHeaderView
android:id="@+id/post_header"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/lm_feed_large_margin"
android:layout_marginBottom="@dimen/lm_feed_regular_margin"
app:layout_constraintBottom_toTopOf="@id/tv_post_content"
app:layout_constraintEnd_toStartOf="@id/post_action_view"
app:layout_constraintStart_toStartOf="parent" />
<com.likeminds.feed.android.core.ui.base.views.LMFeedChipGroup
android:id="@+id/post_topics_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/lm_feed_regular_margin"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/post_header" />
<com.likeminds.feed.android.core.ui.base.views.LMFeedTextView
android:id="@+id/tv_post_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/lm_feed_large_margin"
android:layout_marginEnd="@dimen/lm_feed_extra_extra_large_margin"
android:layout_marginBottom="@dimen/lm_feed_large_margin"
android:lineSpacingExtra="@dimen/lm_feed_line_spacing_extra_extra_small"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/post_action_view"
app:layout_constraintStart_toStartOf="parent"
tools:fontFamily="@font/lm_feed_roboto"
tools:textColor="@color/lm_feed_grey"
tools:textSize="@dimen/lm_feed_text_large" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/post_action_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/lm_feed_large_margin"
android:layout_marginBottom="@dimen/lm_feed_vertical_post_action_bottom_margin"
android:padding="@dimen/lm_feed_small_padding"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:background="?android:attr/selectableItemBackground">
<com.likeminds.feed.android.core.ui.base.views.LMFeedIcon
android:id="@+id/iv_cta"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:padding="@dimen/lm_feed_small_padding"
android:scaleType="fitCenter"
android:tint="@color/white"
android:visibility="visible"
app:layout_constraintBottom_toTopOf="@id/iv_like"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="@drawable/ic_video_feed_invest"
tools:ignore="ContentDescription"
tools:visibility="visible" />
<com.likeminds.feed.android.core.ui.base.views.LMFeedIcon
android:id="@+id/iv_like"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/lm_feed_small_padding"
android:scaleType="fitCenter"
android:visibility="visible"
app:layout_constraintBottom_toTopOf="@id/tv_likes_count"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="ContentDescription"
tools:srcCompat="@drawable/lm_feed_ic_like_filled"
tools:visibility="visible" />
<com.likeminds.feed.android.core.ui.base.views.LMFeedTextView
android:id="@+id/tv_likes_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/lm_feed_medium_margin"
android:foreground="?selectableItemBackground"
android:textStyle="normal"
android:visibility="visible"
app:layout_constraintBottom_toTopOf="@id/iv_comment"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:fontFamily="@font/lm_feed_roboto"
tools:ignore="UnusedAttribute"
tools:text="31k"
tools:textColor="@color/lm_feed_grey"
tools:textSize="@dimen/lm_feed_text_medium" />
<com.likeminds.feed.android.core.ui.base.views.LMFeedIcon
android:id="@+id/iv_post_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/lm_feed_small_padding"
android:scaleType="fitCenter"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="ContentDescription,UnusedAttribute"
tools:src="@drawable/lm_feed_ic_overflow_menu"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Extend PostViewDataBinder
Once, layout file is created. Now create a CustomVideoThemeViewDataBinder
which will extend PostViewDataBinder
to get some default functionality and get PostViewData
which will have all the data related to that post.
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import com.likeminds.feed.android.core.R
import com.likeminds.feed.android.core.socialfeed.adapter.LMFeedPostAdapterListener
import com.likeminds.feed.android.core.socialfeed.model.LMFeedPostViewData
import com.likeminds.feed.android.core.socialfeed.util.LMFeedPostBinderUtils
import com.likeminds.feed.android.core.utils.LMFeedStyleTransformer
import com.likeminds.feed.android.core.utils.LMFeedValueUtils.getFormatedNumber
import com.likeminds.feed.android.core.utils.base.PostItemViewDataBinder
import com.likeminds.feed.android.core.utils.base.model.ITEM_POST_VIDEO_FEED
import com.likeminds.feedvideo.databinding.ItemCustomReelsViewDataBinderBinding
class CustomVideoThemeViewDataBinder(
private val postAdapterListener: LMFeedPostAdapterListener
) : PostItemViewDataBinder<ItemCustomVideoThemeViewBinding>(postAdapterListener) {
override val viewType: Int
get() = ITEM_POST_VIDEO_FEED
override fun createBinder(parent: ViewGroup): ItemCustomVideoThemeViewBinding {
val binding = ItemCustomVideoThemeViewBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
binding.apply {
LMFeedPostBinderUtils.customizePostHeaderView(postHeader)
LMFeedPostBinderUtils.customizePostContentView(tvPostContent)
//set video media style to post video view
val postVerticalVideoMediaStyle =
LMFeedStyleTransformer.postViewStyle.postMediaViewStyle.postVerticalVideoMediaStyle
?: return@apply
postVideoView.setStyle(postVerticalVideoMediaStyle)
LMFeedStyleTransformer.postViewStyle.postActionViewStyle.menuIconStyle?.let {
ivPostMenu.setStyle(
it
)
}
setClickListeners(this)
}
return binding
}
override fun bindData(
binding: ItemCustomVideoThemeViewBinding,
data: LMFeedPostViewData,
position: Int
) {
binding.apply {
this.position = position
postViewData = data
val iconStyle = LMFeedStyleTransformer.postViewStyle.postActionViewStyle.likeIconStyle
val likeIcon = if (data.actionViewData.isLiked) {
iconStyle.activeSrc
} else {
iconStyle.inActiveSrc
}
if (likeIcon != null) {
binding.ivLike.setImageDrawable(
ContextCompat.getDrawable(
root.context,
likeIcon
)
)
}
val likesCount = data.actionViewData.likesCount
val likesCountText = if (likesCount == 0) {
root.context.getString(R.string.lm_feed_like)
} else {
likesCount.toLong().getFormatedNumber()
}
tvLikesCount.text = likesCountText
// checks whether to bind complete data or not and execute corresponding lambda function
LMFeedPostBinderUtils.setPostBindData(
postHeader,
tvPostContent,
data,
position,
postTopicsGroup,
postAdapterListener,
returnBinder = {
return@setPostBindData
}, executeBinder = {}
)
}
}
private fun setClickListeners(binding: ItemCustomVideoThemeViewBinding) {
binding.apply {
postHeader.setAuthorFrameClickListener {
val post = this.postViewData ?: return@setAuthorFrameClickListener
postAdapterListener.onPostAuthorHeaderClicked(position, post)
}
ivLike.setOnClickListener {
val post = this.postViewData ?: return@setOnClickListener
val updatedPost = LMFeedPostBinderUtils.updatePostForLike(post)
postAdapterListener.onPostLikeClicked(position, updatedPost)
}
ivPostMenu.setOnClickListener {
val post = this.postViewData ?: return@setOnClickListener
postAdapterListener.onPostActionMenuClicked(position, post)
}
}
}
}
Replace Default Post View
Now, create a custom fragment to replace the default video theme view databinder and override customizeVideoFeedListView()
and replaceVideoView()
import androidx.core.view.get
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.likeminds.feed.android.core.socialfeed.model.LMFeedPostViewData
import com.likeminds.feed.android.core.ui.widgets.post.postmedia.view.LMFeedPostVerticalVideoMediaView
import com.likeminds.feed.android.core.utils.base.LMFeedDataBoundViewHolder
import com.likeminds.feed.android.core.utils.base.model.ITEM_POST_VIDEO_FEED
import com.likeminds.feed.android.core.videofeed.adapter.LMFeedVideoFeedAdapter
import com.likeminds.feed.android.core.videofeed.view.LMFeedVideoFeedFragment
import com.likeminds.feedvideo.databinding.ItemCustomReelsViewDataBinderBinding
class CustomVideoFeedFragment : LMFeedVideoFeedFragment() {
override fun customizeVideoFeedListView(
vp2VideoFeed: ViewPager2,
videoFeedAdapter: LMFeedVideoFeedAdapter
) {
val customVideoThemeViewDataBinder = CustomVideoThemeViewDataBinder(this)
videoFeedAdapter.replaceViewDataBinder(ITEM_POST_VIDEO_FEED, customVideoThemeViewDataBinder)
}
override fun replaceVideoView(position: Int): LMFeedPostVerticalVideoMediaView? {
//get the video feed binding to play the view in [postVideoView]
val videoFeedBinding =
((binding.vp2VideoFeed[0] as? RecyclerView)?.findViewHolderForAdapterPosition(position) as? LMFeedDataBoundViewHolder<*>)
?.binding as? ItemCustomReelsViewDataBinderBinding ?: return null
return (videoFeedBinding.postVideoView)
}
}
Inflate the CustomVideoFeedFragment
Transact the custom fragment CustomVideoFeedFragment()
created above in the successCallback
of LMFeedCore.showFeed()
which was used in the Getting Started
val successCallback = { response : UserResponse? ->
// inflate universal feed fragment in your activity
val containerViewId = R.id.frame_layout
val fragment = CustomVideoFeedFragment() //custom fragment created
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(containerViewId, fragment, containerViewId.toString())
transaction.commit()
Unit
} // callback triggered when the initiate user call is successful
val failureCallback = { errorMessage ->
Log.e("Example", errorMessage)
Unit
} // callback triggered when the initiate user call fails
LMFeedCore.showFeed(
context = context,
apiKey = apiKey,
uuid = userId,
userName = userName,
success = successCallback,
error = failureCallback
)