WIP barra colapsable en pantalla de perfil y trae informacion de perfil
This commit is contained in:
parent
7f6f96a005
commit
b719cce98d
@ -15,6 +15,7 @@ import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.isolaatti.BuildConfig
|
||||
import com.isolaatti.R
|
||||
@ -25,6 +26,9 @@ import com.isolaatti.posting.PostViewerActivity
|
||||
import com.isolaatti.posting.posts.presentation.PostsViewModel
|
||||
import com.isolaatti.posting.comments.presentation.BottomSheetPostComments
|
||||
import com.isolaatti.posting.common.domain.OnUserInteractedWithPostCallback
|
||||
import com.isolaatti.posting.common.options_bottom_sheet.domain.OptionClicked
|
||||
import com.isolaatti.posting.common.options_bottom_sheet.domain.Options
|
||||
import com.isolaatti.posting.common.options_bottom_sheet.presentation.BottomSheetPostOptionsViewModel
|
||||
import com.isolaatti.posting.common.options_bottom_sheet.ui.BottomSheetPostOptionsFragment
|
||||
import com.isolaatti.posting.posts.presentation.PostsRecyclerViewAdapter
|
||||
import com.isolaatti.posting.posts.ui.CreatePostActivity
|
||||
@ -45,11 +49,14 @@ class FeedFragment : Fragment(), OnUserInteractedWithPostCallback {
|
||||
|
||||
companion object {
|
||||
fun newInstance() = FeedFragment()
|
||||
const val CALLER_ID = 20
|
||||
}
|
||||
|
||||
private val viewModel: PostsViewModel by activityViewModels()
|
||||
private val errorViewModel: ErrorMessageViewModel by activityViewModels()
|
||||
private val screenViewModel: FeedViewModel by viewModels()
|
||||
val optionsViewModel: BottomSheetPostOptionsViewModel by activityViewModels()
|
||||
|
||||
private lateinit var viewBinding: FragmentFeedBinding
|
||||
private lateinit var adapter: PostsRecyclerViewAdapter
|
||||
|
||||
@ -59,6 +66,22 @@ class FeedFragment : Fragment(), OnUserInteractedWithPostCallback {
|
||||
}
|
||||
}
|
||||
|
||||
val optionsObserver: Observer<OptionClicked> = Observer {
|
||||
if(it.callerId == CALLER_ID) {
|
||||
when(it.optionId) {
|
||||
Options.Option.OPTION_DELETE -> {
|
||||
|
||||
}
|
||||
Options.Option.OPTION_EDIT -> {
|
||||
|
||||
}
|
||||
Options.Option.OPTION_REPORT -> {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
@ -175,6 +198,8 @@ class FeedFragment : Fragment(), OnUserInteractedWithPostCallback {
|
||||
}
|
||||
}
|
||||
screenViewModel.getProfile()
|
||||
|
||||
optionsViewModel.optionClicked.observe(viewLifecycleOwner, optionsObserver)
|
||||
}
|
||||
|
||||
fun onNewMenuItemClicked(v: View) {
|
||||
@ -187,6 +212,7 @@ class FeedFragment : Fragment(), OnUserInteractedWithPostCallback {
|
||||
override fun onUnLiked(postId: Long) = viewModel.unLikePost(postId)
|
||||
|
||||
override fun onOptions(postId: Long) {
|
||||
optionsViewModel.setOptions(Options.postOptions, CALLER_ID)
|
||||
val modalBottomSheet = BottomSheetPostOptionsFragment()
|
||||
modalBottomSheet.show(requireActivity().supportFragmentManager, BottomSheetPostOptionsFragment.TAG)
|
||||
}
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
package com.isolaatti.profile.domain.use_case
|
||||
|
||||
import com.isolaatti.posting.posts.data.remote.FeedDto
|
||||
import com.isolaatti.posting.posts.data.remote.FeedFilterDto
|
||||
import com.isolaatti.posting.posts.domain.PostsRepository
|
||||
import com.isolaatti.utils.Resource
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import javax.inject.Inject
|
||||
|
||||
class GetProfilePosts @Inject constructor(private val postsRepository: PostsRepository) {
|
||||
operator fun invoke(userId: Int, lastId: Long, olderFirst: Boolean, filter: FeedFilterDto): Flow<Resource<FeedDto>> =
|
||||
postsRepository.getProfilePosts(userId, lastId, olderFirst, filter)
|
||||
}
|
||||
@ -3,17 +3,40 @@ package com.isolaatti.profile.presentation
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.isolaatti.posting.posts.data.remote.FeedDto
|
||||
import com.isolaatti.profile.data.remote.UserProfileDto
|
||||
import com.isolaatti.profile.domain.ProfileRepository
|
||||
import com.isolaatti.profile.domain.use_case.GetProfile
|
||||
import com.isolaatti.profile.domain.use_case.GetProfilePosts
|
||||
import com.isolaatti.utils.Resource
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class ProfileViewModel @Inject constructor(private val profileRepository: ProfileRepository) : ViewModel() {
|
||||
class ProfileViewModel @Inject constructor(private val getProfileUseCase: GetProfile, private val getProfilePosts: GetProfilePosts) : ViewModel() {
|
||||
private val _profile = MutableLiveData<UserProfileDto>()
|
||||
val profile: LiveData<UserProfileDto> get() = _profile
|
||||
|
||||
private val _posts = MutableLiveData<FeedDto>()
|
||||
val posts: LiveData<FeedDto> get() = _posts
|
||||
|
||||
fun getProfile(profileId: Int) {
|
||||
viewModelScope.launch {
|
||||
getProfileUseCase(profileId).onEach {
|
||||
if(it is Resource.Success) {
|
||||
_profile.postValue(it.data!!)
|
||||
}
|
||||
}.flowOn(Dispatchers.IO).launchIn(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun getPosts(profileId: Int, refresh: Boolean) {
|
||||
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@ package com.isolaatti.profile.ui
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.activity.addCallback
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
@ -13,6 +14,8 @@ import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.viewpager.widget.PagerAdapter
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import androidx.viewpager2.adapter.FragmentViewHolder
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
import com.google.android.material.appbar.AppBarLayout.OnOffsetChangedListener
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import com.isolaatti.R
|
||||
import com.isolaatti.databinding.ActivityProfileBinding
|
||||
@ -24,35 +27,19 @@ import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@AndroidEntryPoint
|
||||
class ProfileActivity : AppCompatActivity() {
|
||||
class ViewPagerAdapter(activity: FragmentActivity) : FragmentStateAdapter(activity) {
|
||||
override fun getItemCount(): Int = 3
|
||||
|
||||
override fun createFragment(position: Int): Fragment {
|
||||
return when(position) {
|
||||
0 -> {
|
||||
DiscussionsFragment()
|
||||
}
|
||||
1 -> {
|
||||
AudiosFragment()
|
||||
}
|
||||
2 -> {
|
||||
ImagesFragment()
|
||||
}
|
||||
else -> {Fragment()}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
lateinit var viewBinding: ActivityProfileBinding
|
||||
private val viewModel: ProfileViewModel by viewModels()
|
||||
private var userId: Int? = null
|
||||
|
||||
private var title = ""
|
||||
|
||||
private val profileObserver = Observer<UserProfileDto> { profile ->
|
||||
Picasso.get()
|
||||
.load(UrlGen.userProfileImage(profile.id))
|
||||
.into(viewBinding.profileImageView)
|
||||
|
||||
title = profile.name
|
||||
viewBinding.textViewUsername.text = profile.name
|
||||
viewBinding.textViewDescription.text = profile.descriptionText
|
||||
}
|
||||
@ -60,27 +47,34 @@ class ProfileActivity : AppCompatActivity() {
|
||||
super.onCreate(savedInstanceState)
|
||||
viewBinding = ActivityProfileBinding.inflate(layoutInflater)
|
||||
setContentView(viewBinding.root)
|
||||
userId = intent.extras?.getInt(EXTRA_USER_ID)
|
||||
var scrollRange = -1
|
||||
var isShow = false
|
||||
viewBinding.topAppBarLayout.addOnOffsetChangedListener(object: OnOffsetChangedListener {
|
||||
|
||||
|
||||
override fun onOffsetChanged(appBarLayout: AppBarLayout, verticalOffset: Int) {
|
||||
if (scrollRange == -1) scrollRange = appBarLayout.totalScrollRange
|
||||
if(scrollRange + verticalOffset == 0) {
|
||||
viewBinding.collapsingToolbarLayout.title = title
|
||||
isShow = true
|
||||
} else if(isShow) {
|
||||
viewBinding.collapsingToolbarLayout.title = " "
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
viewBinding.profileViewPager2.adapter = ViewPagerAdapter(this)
|
||||
viewBinding.topAppBar.setNavigationOnClickListener {
|
||||
finish()
|
||||
}
|
||||
|
||||
TabLayoutMediator(viewBinding.profileTabLayout, viewBinding.profileViewPager2) {tab, position ->
|
||||
when(position) {
|
||||
0 -> {
|
||||
tab.text = getText(R.string.discussions)
|
||||
}
|
||||
1 -> {
|
||||
tab.text = getText(R.string.audios)
|
||||
}
|
||||
2 -> {
|
||||
tab.text = getText(R.string.images)
|
||||
}
|
||||
}
|
||||
}.attach()
|
||||
|
||||
viewModel.profile.observe(this, profileObserver)
|
||||
|
||||
userId?.let { viewModel.getProfile(it) }
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout 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"
|
||||
android:layout_width="match_parent"
|
||||
@ -9,125 +9,112 @@
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/topAppBar_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/top_app_bar"
|
||||
style="@style/Theme.Isolaatti"
|
||||
android:layout_height="wrap_content">
|
||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
android:id="@+id/collapsing_toolbar_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:navigationIcon="@drawable/baseline_arrow_back_24"
|
||||
app:navigationIconTint="@color/on_surface"
|
||||
app:title="Profile"
|
||||
app:titleCentered="true" />
|
||||
android:layout_height="410dp"
|
||||
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
|
||||
app:contentScrim="@color/purple">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="350dp"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginTop="56dp">
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/profile_image_view"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="120dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:shapeAppearance="@style/ShapeAppearanceOverlay.Avatar"
|
||||
tools:srcCompat="@tools:sample/avatars" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_view_username"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_weight="1"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/profile_image_view"
|
||||
tools:text="Erik Cavazos" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_view_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
android:maxLines="4"
|
||||
android:textAlignment="center"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_view_username"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
tools:text="Hi there, I am software developer!" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_view_following_state"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:textAlignment="center"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_view_description"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
tools:text="Following this profile" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
style="?attr/materialIconButtonFilledTonalStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
|
||||
app:layout_constraintEnd_toStartOf="@id/profile_options_button"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_view_following_state" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/profile_options_button"
|
||||
style="?attr/materialIconButtonFilledTonalStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
app:icon="@drawable/baseline_more_horiz_24"
|
||||
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_view_following_state"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/top_app_bar"
|
||||
style="@style/Theme.Isolaatti"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:navigationIcon="@drawable/baseline_arrow_back_24"
|
||||
app:navigationIconTint="@color/on_surface"
|
||||
app:layout_collapseMode="pin" />
|
||||
|
||||
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/topAppBar_layout">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/profile_image_view"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="120dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:shapeAppearance="@style/ShapeAppearanceOverlay.Avatar"
|
||||
tools:srcCompat="@tools:sample/avatars" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_view_username"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_weight="1"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/profile_image_view"
|
||||
tools:text="Erik Cavazos" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_view_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
android:maxLines="4"
|
||||
android:textAlignment="center"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_view_username"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
tools:text="Hi there, I am software developer!" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_view_following_state"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:textAlignment="center"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_view_description"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
tools:text="Following this profile" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
style="?attr/materialIconButtonFilledTonalStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
|
||||
app:layout_constraintEnd_toStartOf="@id/profile_options_button"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_view_following_state" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/profile_options_button"
|
||||
style="?attr/materialIconButtonFilledTonalStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
app:icon="@drawable/baseline_more_horiz_24"
|
||||
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_view_following_state"/>
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/feed_recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"/>
|
||||
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/profile_tab_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:tabContentStart="56dp"
|
||||
app:tabMode="fixed"
|
||||
app:layout_constraintTop_toBottomOf="@id/profile_options_button"/>
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/profile_view_pager2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/profile_tab_layout"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
@ -13,4 +13,7 @@
|
||||
<item name="cornerSize">50%</item>
|
||||
</style>
|
||||
|
||||
<style name="TransparentText" parent="@android:style/TextAppearance">
|
||||
<item name="android:textColor">#00000000</item>
|
||||
</style>
|
||||
</resources>
|
||||
Loading…
x
Reference in New Issue
Block a user