Use view binding more

This commit is contained in:
Matthieu 2021-01-13 22:46:00 +01:00
parent 79c0d5c0b4
commit 6fa4488296
6 changed files with 118 additions and 138 deletions

View File

@ -88,9 +88,7 @@ class PostCreationActivity : BaseActivity() {
val instances = db.instanceDao().getAll() val instances = db.instanceDao().getAll()
val textField = findViewById<TextInputLayout>(R.id.postTextInputLayout) binding.postTextInputLayout.counterMaxLength = if (user != null){
textField.counterMaxLength = if (user != null){
val thisInstances = val thisInstances =
instances.filter { instanceDatabaseEntity -> instances.filter { instanceDatabaseEntity ->
instanceDatabaseEntity.uri.contains(user!!.instance_uri) instanceDatabaseEntity.uri.contains(user!!.instance_uri)
@ -103,7 +101,7 @@ class PostCreationActivity : BaseActivity() {
accessToken = user?.accessToken.orEmpty() accessToken = user?.accessToken.orEmpty()
pixelfedAPI = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db) pixelfedAPI = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
val carousel: ImageCarousel = findViewById(R.id.carousel) val carousel: ImageCarousel = binding.carousel
carousel.addData(photoData.map { CarouselItem(it.imageUri.toString()) }) carousel.addData(photoData.map { CarouselItem(it.imageUri.toString()) })
carousel.layoutCarouselCallback = { carousel.layoutCarouselCallback = {
//TODO transition instead of at once //TODO transition instead of at once
@ -120,12 +118,12 @@ class PostCreationActivity : BaseActivity() {
} }
// get the description and send the post // get the description and send the post
findViewById<Button>(R.id.post_creation_send_button).setOnClickListener { binding.postCreationSendButton.setOnClickListener {
if (validateDescription() && photoData.isNotEmpty()) upload() if (validateDescription() && photoData.isNotEmpty()) upload()
} }
// Button to retry image upload when it fails // Button to retry image upload when it fails
findViewById<Button>(R.id.retry_upload_button).setOnClickListener { binding.retryUploadButton.setOnClickListener {
binding.uploadError.visibility = View.GONE binding.uploadError.visibility = View.GONE
photoData.forEach { photoData.forEach {
it.uploadId = null it.uploadId = null
@ -134,24 +132,24 @@ class PostCreationActivity : BaseActivity() {
upload() upload()
} }
findViewById<ImageButton>(R.id.editPhotoButton).setOnClickListener { binding.editPhotoButton.setOnClickListener {
carousel.currentPosition.takeIf { it != -1 }?.let { currentPosition -> carousel.currentPosition.takeIf { it != -1 }?.let { currentPosition ->
edit(currentPosition) edit(currentPosition)
} }
} }
findViewById<ImageButton>(R.id.addPhotoButton).setOnClickListener { binding.addPhotoButton.setOnClickListener {
addPhoto(it.context) addPhoto(it.context)
} }
findViewById<ImageButton>(R.id.savePhotoButton).setOnClickListener { binding.savePhotoButton.setOnClickListener {
carousel.currentPosition.takeIf { it != -1 }?.let { currentPosition -> carousel.currentPosition.takeIf { it != -1 }?.let { currentPosition ->
savePicture(it, currentPosition) savePicture(it, currentPosition)
} }
} }
findViewById<ImageButton>(R.id.removePhotoButton).setOnClickListener { binding.removePhotoButton.setOnClickListener {
carousel.currentPosition.takeIf { it != -1 }?.let { currentPosition -> carousel.currentPosition.takeIf { it != -1 }?.let { currentPosition ->
photoData.removeAt(currentPosition) photoData.removeAt(currentPosition)
carousel.addData(photoData.map { CarouselItem(it.imageUri.toString()) }) carousel.addData(photoData.map { CarouselItem(it.imageUri.toString()) })
@ -226,12 +224,13 @@ class PostCreationActivity : BaseActivity() {
private fun validateDescription(): Boolean { private fun validateDescription(): Boolean {
val textField = findViewById<TextInputLayout>(R.id.postTextInputLayout) binding.postTextInputLayout.run {
val content = textField.editText?.length() ?: 0 val content = editText?.length() ?: 0
if (content > textField.counterMaxLength) { if (content > counterMaxLength) {
// error, too many characters // error, too many characters
textField.error = getString(R.string.description_max_characters).format(textField.counterMaxLength) error = getString(R.string.description_max_characters).format(counterMaxLength)
return false return false
}
} }
return true return true
} }

View File

@ -65,9 +65,6 @@ class PhotoEditActivity : BaseActivity() {
private lateinit var filterListFragment: FilterListFragment private lateinit var filterListFragment: FilterListFragment
private lateinit var editImageFragment: EditImageFragment private lateinit var editImageFragment: EditImageFragment
private lateinit var viewPager: NonSwipeableViewPager
private lateinit var tabLayout: TabLayout
private var brightnessFinal = BRIGHTNESS_START private var brightnessFinal = BRIGHTNESS_START
private var saturationFinal = SATURATION_START private var saturationFinal = SATURATION_START
private var contrastFinal = CONTRAST_START private var contrastFinal = CONTRAST_START
@ -100,22 +97,18 @@ class PhotoEditActivity : BaseActivity() {
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setHomeButtonEnabled(true) supportActionBar?.setHomeButtonEnabled(true)
val cropButton: FloatingActionButton = findViewById(R.id.cropImageButton)
initialUri = intent.getParcelableExtra("picture_uri") initialUri = intent.getParcelableExtra("picture_uri")
imageUri = initialUri imageUri = initialUri
// Crop button on-click listener // Crop button on-click listener
cropButton.setOnClickListener { binding.cropImageButton.setOnClickListener {
startCrop() startCrop()
} }
loadImage() loadImage()
viewPager = findViewById(R.id.viewPager) setupViewPager(binding.viewPager)
tabLayout = findViewById(R.id.tabs) binding.tabs.setupWithViewPager(binding.viewPager)
setupViewPager(viewPager)
tabLayout.setupWithViewPager(viewPager)
} }

View File

@ -181,7 +181,7 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold
credential: String, credential: String,
lifecycleScope: LifecycleCoroutineScope lifecycleScope: LifecycleCoroutineScope
) { ) {
rootView.findViewById<TextView>(R.id.description).apply { binding.description.apply {
if (status?.content.isNullOrBlank()) { if (status?.content.isNullOrBlank()) {
visibility = View.GONE visibility = View.GONE
} else { } else {

View File

@ -14,14 +14,14 @@ import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.h.pixeldroid.R import com.h.pixeldroid.R
import com.h.pixeldroid.utils.api.PixelfedAPI import com.h.pixeldroid.databinding.ActivityProfileBinding
import com.h.pixeldroid.utils.db.entities.UserDatabaseEntity
import com.h.pixeldroid.utils.api.objects.Account
import com.h.pixeldroid.utils.api.objects.Relationship
import com.h.pixeldroid.utils.api.objects.Status
import com.h.pixeldroid.posts.parseHTMLText import com.h.pixeldroid.posts.parseHTMLText
import com.h.pixeldroid.utils.BaseActivity import com.h.pixeldroid.utils.BaseActivity
import com.h.pixeldroid.utils.ImageConverter import com.h.pixeldroid.utils.ImageConverter
import com.h.pixeldroid.utils.api.PixelfedAPI
import com.h.pixeldroid.utils.api.objects.Account
import com.h.pixeldroid.utils.api.objects.Status
import com.h.pixeldroid.utils.db.entities.UserDatabaseEntity
import com.h.pixeldroid.utils.openUrl import com.h.pixeldroid.utils.openUrl
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import retrofit2.Call import retrofit2.Call
@ -33,16 +33,17 @@ import java.io.IOException
class ProfileActivity : BaseActivity() { class ProfileActivity : BaseActivity() {
private lateinit var pixelfedAPI : PixelfedAPI private lateinit var pixelfedAPI : PixelfedAPI
private lateinit var adapter : ProfilePostsRecyclerViewAdapter private lateinit var adapter : ProfilePostsRecyclerViewAdapter
private lateinit var recycler : RecyclerView
private lateinit var refreshLayout: SwipeRefreshLayout
private lateinit var accessToken : String private lateinit var accessToken : String
private lateinit var domain : String private lateinit var domain : String
private var user: UserDatabaseEntity? = null private var user: UserDatabaseEntity? = null
private lateinit var binding: ActivityProfileBinding
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_profile) binding = ActivityProfileBinding.inflate(layoutInflater)
setContentView(binding.root)
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
user = db.userDao().getActiveUser() user = db.userDao().getActiveUser()
@ -52,19 +53,16 @@ class ProfileActivity : BaseActivity() {
accessToken = user?.accessToken.orEmpty() accessToken = user?.accessToken.orEmpty()
// Set posts RecyclerView as a grid with 3 columns // Set posts RecyclerView as a grid with 3 columns
recycler = findViewById(R.id.profilePostsRecyclerView) binding.profilePostsRecyclerView.layoutManager = GridLayoutManager(applicationContext, 3)
recycler.layoutManager = GridLayoutManager(applicationContext, 3)
adapter = ProfilePostsRecyclerViewAdapter() adapter = ProfilePostsRecyclerViewAdapter()
recycler.adapter = adapter binding.profilePostsRecyclerView.adapter = adapter
// Set profile according to given account // Set profile according to given account
val account = intent.getSerializableExtra(Account.ACCOUNT_TAG) as Account? val account = intent.getSerializableExtra(Account.ACCOUNT_TAG) as Account?
setContent(account) setContent(account)
refreshLayout = findViewById(R.id.profileRefreshLayout) binding.profileRefreshLayout.setOnRefreshListener {
refreshLayout.setOnRefreshListener {
getAndSetAccount(account?.id ?: user!!.user_id) getAndSetAccount(account?.id ?: user!!.user_id)
} }
} }
@ -101,9 +99,9 @@ class ProfileActivity : BaseActivity() {
// On click open followers list // On click open followers list
findViewById<TextView>(R.id.nbFollowersTextView).setOnClickListener{ onClickFollowers(account) } binding.nbFollowersTextView.setOnClickListener{ onClickFollowers(account) }
// On click open followers list // On click open followers list
findViewById<TextView>(R.id.nbFollowingTextView).setOnClickListener{ onClickFollowing(account) } binding.nbFollowingTextView.setOnClickListener{ onClickFollowing(account) }
} }
private fun getAndSetAccount(id: String){ private fun getAndSetAccount(id: String){
@ -121,59 +119,50 @@ class ProfileActivity : BaseActivity() {
} }
private fun showError(@StringRes errorText: Int = R.string.loading_toast, show: Boolean = true){ private fun showError(@StringRes errorText: Int = R.string.loading_toast, show: Boolean = true){
val motionLayout = findViewById<MotionLayout>(R.id.motionLayout) val motionLayout = binding.motionLayout
if(show){ if(show){
motionLayout?.transitionToEnd() motionLayout.transitionToEnd()
} else { } else {
motionLayout?.transitionToStart() motionLayout.transitionToStart()
} }
findViewById<ProgressBar>(R.id.profileProgressBar).visibility = View.GONE binding.profileProgressBar.visibility = View.GONE
refreshLayout.isRefreshing = false binding.profileRefreshLayout.isRefreshing = false
} }
/** /**
* Populate profile page with user's data * Populate profile page with user's data
*/ */
private fun setViews(account: Account) { private fun setViews(account: Account) {
val profilePicture = findViewById<ImageView>(R.id.profilePictureImageView) val profilePicture = binding.profilePictureImageView
ImageConverter.setRoundImageFromURL( ImageConverter.setRoundImageFromURL(
View(applicationContext), View(applicationContext),
account.avatar, account.avatar,
profilePicture profilePicture
) )
val description = findViewById<TextView>(R.id.descriptionTextView) binding.descriptionTextView.text = parseHTMLText(
description.text = parseHTMLText(
account.note ?: "", emptyList(), pixelfedAPI, account.note ?: "", emptyList(), pixelfedAPI,
applicationContext, "Bearer $accessToken", applicationContext, "Bearer $accessToken",
lifecycleScope lifecycleScope
) )
val accountName = findViewById<TextView>(R.id.accountNameTextView)
accountName.text = account.getDisplayName()
val displayName = account.getDisplayName() val displayName = account.getDisplayName()
binding.accountNameTextView.text = displayName
supportActionBar?.title = displayName supportActionBar?.title = displayName
if(displayName != "@${account.acct}"){ if(displayName != "@${account.acct}"){
supportActionBar?.subtitle = "@${account.acct}" supportActionBar?.subtitle = "@${account.acct}"
} }
accountName.setTypeface(null, Typeface.BOLD) binding.nbPostsTextView.text = applicationContext.getString(R.string.nb_posts)
val nbPosts = findViewById<TextView>(R.id.nbPostsTextView)
nbPosts.text = applicationContext.getString(R.string.nb_posts)
.format(account.statuses_count.toString()) .format(account.statuses_count.toString())
nbPosts.setTypeface(null, Typeface.BOLD)
val nbFollowers = findViewById<TextView>(R.id.nbFollowersTextView) binding.nbFollowersTextView.text = applicationContext.getString(R.string.nb_followers)
nbFollowers.text = applicationContext.getString(R.string.nb_followers)
.format(account.followers_count.toString()) .format(account.followers_count.toString())
nbFollowers.setTypeface(null, Typeface.BOLD)
val nbFollowing = findViewById<TextView>(R.id.nbFollowingTextView) binding.nbFollowingTextView.text = applicationContext.getString(R.string.nb_following)
nbFollowing.text = applicationContext.getString(R.string.nb_following)
.format(account.following_count.toString()) .format(account.following_count.toString())
nbFollowing.setTypeface(null, Typeface.BOLD)
} }
/** /**
@ -227,9 +216,10 @@ class ProfileActivity : BaseActivity() {
private fun activateEditButton() { private fun activateEditButton() {
// Edit button redirects to Pixelfed's "edit account" page // Edit button redirects to Pixelfed's "edit account" page
val editButton = findViewById<Button>(R.id.editButton) binding.editButton.apply {
editButton.visibility = View.VISIBLE visibility = View.VISIBLE
editButton.setOnClickListener{ onClickEditButton() } setOnClickListener{ onClickEditButton() }
}
} }
/** /**
@ -244,14 +234,12 @@ class ProfileActivity : BaseActivity() {
).firstOrNull() ).firstOrNull()
if(relationship != null){ if(relationship != null){
val followButton = findViewById<Button>(R.id.followButton)
if (relationship.following) { if (relationship.following) {
setOnClickUnfollow(account) setOnClickUnfollow(account)
} else { } else {
setOnClickFollow(account) setOnClickFollow(account)
} }
followButton.visibility = View.VISIBLE binding.followButton.visibility = View.VISIBLE
} }
} catch (exception: IOException) { } catch (exception: IOException) {
Log.e("FOLLOW ERROR", exception.toString()) Log.e("FOLLOW ERROR", exception.toString())
@ -269,53 +257,51 @@ class ProfileActivity : BaseActivity() {
} }
private fun setOnClickFollow(account: Account) { private fun setOnClickFollow(account: Account) {
val followButton = findViewById<Button>(R.id.followButton) binding.followButton.apply {
setText(R.string.follow)
followButton.setText(R.string.follow) setOnClickListener {
lifecycleScope.launchWhenResumed {
followButton.setOnClickListener { try {
lifecycleScope.launchWhenResumed { pixelfedAPI.follow(account.id.orEmpty(), "Bearer $accessToken")
try { setOnClickUnfollow(account)
pixelfedAPI.follow(account.id.orEmpty(), "Bearer $accessToken") } catch (exception: IOException) {
setOnClickUnfollow(account) Log.e("FOLLOW ERROR", exception.toString())
} catch (exception: IOException) { Toast.makeText(
Log.e("FOLLOW ERROR", exception.toString()) applicationContext, getString(R.string.follow_error),
Toast.makeText( Toast.LENGTH_SHORT
applicationContext, getString(R.string.follow_error), ).show()
Toast.LENGTH_SHORT } catch (exception: HttpException) {
).show() Toast.makeText(
} catch (exception: HttpException) { applicationContext, getString(R.string.follow_error),
Toast.makeText( Toast.LENGTH_SHORT
applicationContext, getString(R.string.follow_error), ).show()
Toast.LENGTH_SHORT }
).show()
} }
} }
} }
} }
private fun setOnClickUnfollow(account: Account) { private fun setOnClickUnfollow(account: Account) {
val followButton = findViewById<Button>(R.id.followButton) binding.followButton.apply {
setText(R.string.unfollow)
followButton.setText(R.string.unfollow) setOnClickListener {
lifecycleScope.launchWhenResumed {
followButton.setOnClickListener { try {
pixelfedAPI.unfollow(account.id.orEmpty(), "Bearer $accessToken")
lifecycleScope.launchWhenResumed { setOnClickFollow(account)
try { } catch (exception: IOException) {
pixelfedAPI.unfollow(account.id.orEmpty(), "Bearer $accessToken") Log.e("FOLLOW ERROR", exception.toString())
setOnClickFollow(account) Toast.makeText(
} catch (exception: IOException) { applicationContext, getString(R.string.unfollow_error),
Log.e("FOLLOW ERROR", exception.toString()) Toast.LENGTH_SHORT
Toast.makeText( ).show()
applicationContext, getString(R.string.unfollow_error), } catch (exception: HttpException) {
Toast.LENGTH_SHORT Toast.makeText(
).show() applicationContext, getString(R.string.unfollow_error),
} catch (exception: HttpException) { Toast.LENGTH_SHORT
Toast.makeText( ).show()
applicationContext, getString(R.string.unfollow_error), }
Toast.LENGTH_SHORT
).show()
} }
} }
} }

View File

@ -17,6 +17,8 @@ import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.h.pixeldroid.R import com.h.pixeldroid.R
import com.h.pixeldroid.databinding.FragmentSearchBinding
import com.h.pixeldroid.databinding.PostFragmentBinding
import com.h.pixeldroid.profile.ProfilePostViewHolder import com.h.pixeldroid.profile.ProfilePostViewHolder
import com.h.pixeldroid.utils.api.PixelfedAPI import com.h.pixeldroid.utils.api.PixelfedAPI
import com.h.pixeldroid.utils.api.objects.DiscoverPost import com.h.pixeldroid.utils.api.objects.DiscoverPost
@ -25,6 +27,7 @@ import com.h.pixeldroid.utils.api.objects.Status
import com.h.pixeldroid.posts.PostActivity import com.h.pixeldroid.posts.PostActivity
import com.h.pixeldroid.utils.BaseFragment import com.h.pixeldroid.utils.BaseFragment
import com.h.pixeldroid.utils.ImageConverter import com.h.pixeldroid.utils.ImageConverter
import com.h.pixeldroid.utils.bindingLifecycleAware
import com.mikepenz.iconics.IconicsColor import com.mikepenz.iconics.IconicsColor
import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
@ -46,37 +49,35 @@ class SearchDiscoverFragment : BaseFragment() {
private lateinit var recycler : RecyclerView private lateinit var recycler : RecyclerView
private lateinit var adapter : DiscoverRecyclerViewAdapter private lateinit var adapter : DiscoverRecyclerViewAdapter
private lateinit var accessToken: String private lateinit var accessToken: String
private lateinit var discoverProgressBar: ProgressBar
private lateinit var discoverRefreshLayout: SwipeRefreshLayout var binding: FragmentSearchBinding by bindingLifecycleAware()
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View {
val view = inflater.inflate(R.layout.fragment_search, container, false) binding = FragmentSearchBinding.inflate(inflater, container, false)
val search = view.findViewById<SearchView>(R.id.search)
//Configure the search widget (see https://developer.android.com/guide/topics/search/search-dialog#ConfiguringWidget) // Configure the search widget (see https://developer.android.com/guide/topics/search/search-dialog#ConfiguringWidget)
val searchManager = requireActivity().getSystemService(Context.SEARCH_SERVICE) as SearchManager val searchManager = requireActivity().getSystemService(Context.SEARCH_SERVICE) as SearchManager
search.setSearchableInfo(searchManager.getSearchableInfo(requireActivity().componentName)) binding.search.apply {
setSearchableInfo(searchManager.getSearchableInfo(requireActivity().componentName))
search.isSubmitButtonEnabled = true isSubmitButtonEnabled = true
}
// Set posts RecyclerView as a grid with 3 columns // Set posts RecyclerView as a grid with 3 columns
recycler = view.findViewById(R.id.discoverList) recycler = binding.discoverList
recycler.layoutManager = GridLayoutManager(requireContext(), 3) recycler.layoutManager = GridLayoutManager(requireContext(), 3)
adapter = DiscoverRecyclerViewAdapter() adapter = DiscoverRecyclerViewAdapter()
recycler.adapter = adapter recycler.adapter = adapter
val discoverText = view.findViewById<TextView>(R.id.discoverText) binding.discoverText.setCompoundDrawables(IconicsDrawable(requireContext(), GoogleMaterial.Icon.gmd_explore).apply {
discoverText.setCompoundDrawables(IconicsDrawable(requireContext(), GoogleMaterial.Icon.gmd_explore).apply {
sizeDp = 24 sizeDp = 24
paddingDp = 20 paddingDp = 20
color = IconicsColor.colorRes(R.color.colorDrawing) color = IconicsColor.colorRes(R.color.colorDrawing)
}, null, null, null) }, null, null, null)
return view return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -86,30 +87,27 @@ class SearchDiscoverFragment : BaseFragment() {
accessToken = db.userDao().getActiveUser()?.accessToken.orEmpty() accessToken = db.userDao().getActiveUser()?.accessToken.orEmpty()
discoverProgressBar = view.findViewById(R.id.discoverProgressBar)
discoverRefreshLayout = view.findViewById(R.id.discoverRefreshLayout)
getDiscover() getDiscover()
discoverRefreshLayout.setOnRefreshListener { binding.discoverRefreshLayout.setOnRefreshListener {
getDiscover() getDiscover()
} }
} }
fun showError(@StringRes errorText: Int = R.string.loading_toast, show: Boolean = true){ fun showError(@StringRes errorText: Int = R.string.loading_toast, show: Boolean = true){
val motionLayout = view?.findViewById<MotionLayout>(R.id.motionLayout) binding.motionLayout.apply {
if(show){ if(show){
motionLayout?.transitionToEnd() transitionToEnd()
} else { } else {
motionLayout?.transitionToStart() transitionToStart()
}
} }
discoverRefreshLayout.isRefreshing = false binding.discoverRefreshLayout.isRefreshing = false
discoverProgressBar.visibility = View.GONE binding.discoverProgressBar.visibility = View.GONE
} }
private fun getDiscover() { private fun getDiscover() {
lifecycleScope.launchWhenCreated { lifecycleScope.launchWhenCreated {
try { try {
val discoverPosts = api.discover("Bearer $accessToken") val discoverPosts = api.discover("Bearer $accessToken")

View File

@ -34,6 +34,7 @@
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:gravity="center" android:gravity="center"
android:text="@string/default_nposts" android:text="@string/default_nposts"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/profilePictureImageView" app:layout_constraintBottom_toBottomOf="@+id/profilePictureImageView"
app:layout_constraintHorizontal_chainStyle="spread" app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toEndOf="@+id/profilePictureImageView" app:layout_constraintStart_toEndOf="@+id/profilePictureImageView"
@ -45,6 +46,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
android:text="@string/default_nfollowers" android:text="@string/default_nfollowers"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/nbPostsTextView" app:layout_constraintBottom_toBottomOf="@+id/nbPostsTextView"
app:layout_constraintEnd_toStartOf="@+id/nbFollowingTextView" app:layout_constraintEnd_toStartOf="@+id/nbFollowingTextView"
app:layout_constraintStart_toEndOf="@+id/nbPostsTextView" app:layout_constraintStart_toEndOf="@+id/nbPostsTextView"
@ -57,6 +59,7 @@
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:gravity="center" android:gravity="center"
android:text="@string/default_nfollowing" android:text="@string/default_nfollowing"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/nbFollowersTextView" app:layout_constraintBottom_toBottomOf="@+id/nbFollowersTextView"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/nbFollowersTextView" /> app:layout_constraintTop_toTopOf="@+id/nbFollowersTextView" />
@ -69,9 +72,10 @@
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:layout_marginRight="20dp" android:layout_marginRight="20dp"
android:text="@string/no_username" android:text="@string/no_username"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/profilePictureImageView"/> app:layout_constraintTop_toBottomOf="@id/profilePictureImageView" />
<TextView <TextView