Skip to main content

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.

LMFeedLikeListScreen

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
)