My profile (#46)
* Layout of my-profile page * implements swipe motion add a new class to implement swipe motion add the swipe right from home page to display settings passed the homepage in a fragment * transform profile activity into fragment transformed profile activity and layout into fragment linked it with a swipe motion * Implement swipeable tabs * Ask for login on first start, add API endpoints, change profile to show the user's profile * Added constraint view * Layout of my-profile page * Added constraint view * Rebase myProfile with login-flow * Add tests * delete test for now * Adapt test to changes (no more profile from drawer) * Add unit test for api * Add test for profile, refactor to allow testing, add exception to security policy to allow tests * Adapt test to new situation * Fix typo due to change * refactor somewhat * Added myProfile fragment to main activity + edit link * Layout of my-profile page * Added constraint view * Layout of my-profile page * Added constraint view * Rebase myProfile with login-flow * Added myProfile fragment to main activity + edit link * Working tests for MyProfile Co-authored-by: Ulysse Widmer <ulysse.widmer@epfl.ch>
This commit is contained in:
parent
20c5ff4ee0
commit
8802bf9905
@ -1,6 +1,7 @@
|
||||
package com.h.pixeldroid
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.Intent.ACTION_VIEW
|
||||
import android.net.Uri
|
||||
@ -17,6 +18,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.rule.ActivityTestRule
|
||||
import org.hamcrest.CoreMatchers.allOf
|
||||
import org.hamcrest.CoreMatchers.anyOf
|
||||
@ -90,6 +92,9 @@ class AfterIntent {
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
val preferences = InstrumentationRegistry.getInstrumentation()
|
||||
.targetContext.getSharedPreferences("com.h.pixeldroid.pref", Context.MODE_PRIVATE)
|
||||
preferences.edit().putString("domain", "http://localhost").apply()
|
||||
val intent = Intent(ACTION_VIEW, Uri.parse("oauth2redirect://com.h.pixeldroid?code=sdfdqsf"))
|
||||
launchedActivity = rule.launchActivity(intent)
|
||||
}
|
||||
|
@ -1,22 +1,17 @@
|
||||
package com.h.pixeldroid
|
||||
|
||||
import android.content.Context
|
||||
import androidx.core.view.get
|
||||
import androidx.test.core.app.ActivityScenario
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.action.ViewActions
|
||||
import androidx.test.espresso.action.ViewActions.click
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import com.h.pixeldroid.objects.Account
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import okhttp3.mockwebserver.MockResponse
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
@ -24,7 +19,7 @@ import org.junit.runner.RunWith
|
||||
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ProfileTest {
|
||||
class MyProfileTest {
|
||||
private val accountJson = "{\n" +
|
||||
" \"id\": \"1450\",\n" +
|
||||
" \"username\": \"deerbard_photo\",\n" +
|
||||
@ -52,7 +47,6 @@ class ProfileTest {
|
||||
var activityRule: ActivityScenarioRule<MainActivity>
|
||||
= ActivityScenarioRule(MainActivity::class.java)
|
||||
|
||||
|
||||
@Before
|
||||
fun before(){
|
||||
val server = MockWebServer()
|
||||
@ -71,9 +65,7 @@ class ProfileTest {
|
||||
ViewActions.swipeLeft()
|
||||
).perform(ViewActions.swipeLeft())
|
||||
Thread.sleep(1000)
|
||||
onView(withId(R.id.followers)).check(matches(withText("Followers")))
|
||||
onView(withId(R.id.accountName)).check(matches(withText("deerbard_photo")))
|
||||
|
||||
|
||||
onView(withId(R.id.nbFollowersTextView)).check(matches(withText("68\nFollowers")))
|
||||
onView(withId(R.id.accountNameTextView)).check(matches(withText("deerbard_photo")))
|
||||
}
|
||||
}
|
||||
}
|
@ -34,7 +34,6 @@ class SwipeTest {
|
||||
@Test
|
||||
fun swipingRightOnHomepageShowsSettings() {
|
||||
onView(withId(R.id.view_pager)).perform(swipeLeft()).perform(swipeLeft()).perform(swipeLeft()).perform(swipeLeft())
|
||||
onView(withId(R.id.nbFollowers)).check(matches(isDisplayed()))
|
||||
|
||||
onView(withId(R.id.nbFollowersTextView)).check(matches(isDisplayed()))
|
||||
}
|
||||
}
|
@ -17,7 +17,8 @@ import com.google.android.material.navigation.NavigationView
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import com.h.pixeldroid.fragments.HomeFragment
|
||||
import com.h.pixeldroid.fragments.ProfileFragment
|
||||
import com.h.pixeldroid.fragments.MyProfileFragment
|
||||
|
||||
|
||||
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
|
||||
|
||||
@ -26,7 +27,6 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
|
||||
private lateinit var tabLayout: TabLayout
|
||||
private lateinit var preferences: SharedPreferences
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
@ -45,7 +45,8 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
|
||||
val navigationView: NavigationView = findViewById(R.id.nav_view)
|
||||
navigationView.setNavigationItemSelectedListener(this)
|
||||
|
||||
val tabs = arrayOf(HomeFragment(), Fragment(), Fragment(), Fragment(), ProfileFragment())
|
||||
val tabs = arrayOf(HomeFragment(), Fragment(), Fragment(), Fragment(), MyProfileFragment())
|
||||
|
||||
setupTabs(tabs)
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,17 @@
|
||||
package com.h.pixeldroid.fragments
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
|
||||
import android.graphics.Typeface
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.fragment.app.Fragment
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Button
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.bumptech.glide.Glide
|
||||
@ -17,12 +19,12 @@ import com.h.pixeldroid.BuildConfig
|
||||
import com.h.pixeldroid.R
|
||||
import com.h.pixeldroid.api.PixelfedAPI
|
||||
import com.h.pixeldroid.objects.Account
|
||||
import com.h.pixeldroid.objects.Status
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
|
||||
class ProfileFragment : Fragment() {
|
||||
|
||||
class MyProfileFragment : Fragment() {
|
||||
private lateinit var preferences: SharedPreferences
|
||||
|
||||
override fun onCreateView(
|
||||
@ -32,7 +34,12 @@ class ProfileFragment : Fragment() {
|
||||
preferences = this.activity!!.getSharedPreferences(
|
||||
"${BuildConfig.APPLICATION_ID}.pref", Context.MODE_PRIVATE
|
||||
)
|
||||
return inflater.inflate(R.layout.fragment_profile, container, false)
|
||||
val view = inflater.inflate(R.layout.fragment_my_profile, container, false)
|
||||
|
||||
val editButton: Button = view.findViewById(R.id.editButton)
|
||||
editButton.setOnClickListener((View.OnClickListener { onClickEditButton() }))
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
@ -44,11 +51,10 @@ class ProfileFragment : Fragment() {
|
||||
pixelfedAPI.verifyCredentials("Bearer $accessToken")
|
||||
.enqueue(object : Callback<Account> {
|
||||
override fun onResponse(call: Call<Account>, response: Response<Account>) {
|
||||
if (response.code() == 200) {
|
||||
if(response.code() == 200) {
|
||||
val account = response.body()!!
|
||||
|
||||
setContent(view, account)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,31 +66,42 @@ class ProfileFragment : Fragment() {
|
||||
|
||||
private fun setContent(view: View, account: Account) {
|
||||
// ImageView : profile picture
|
||||
val profilePicture = view.findViewById<ImageView>(R.id.profilePicture)
|
||||
val profilePicture = view.findViewById<ImageView>(R.id.profilePictureImageView)
|
||||
Glide.with(view.context).load(account.avatar).into(profilePicture)
|
||||
|
||||
|
||||
// TextView : description / bio
|
||||
val description = view.findViewById<TextView>(R.id.description)
|
||||
val description = view.findViewById<TextView>(R.id.descriptionTextView)
|
||||
description.text = account.note
|
||||
|
||||
// TextView : account name
|
||||
val accountName = view.findViewById<TextView>(R.id.accountName)
|
||||
val accountName = view.findViewById<TextView>(R.id.accountNameTextView)
|
||||
accountName.text = account.username
|
||||
|
||||
// TextView : number of posts
|
||||
val nbPosts = view.findViewById<TextView>(R.id.nbPosts)
|
||||
nbPosts.text = account.statuses_count.toString()
|
||||
val nbPosts = view.findViewById<TextView>(R.id.nbPostsTextView)
|
||||
nbPosts.text = account.statuses_count.toString() + "\nPosts"
|
||||
nbPosts.setTypeface(null, Typeface.BOLD)
|
||||
|
||||
// TextView : number of followers
|
||||
val nbFollowers = view.findViewById<TextView>(R.id.nbFollowers)
|
||||
nbFollowers.text = account.followers_count.toString()
|
||||
val nbFollowers = view.findViewById<TextView>(R.id.nbFollowersTextView)
|
||||
nbFollowers.text = account.followers_count.toString() + "\nFollowers"
|
||||
nbFollowers.setTypeface(null, Typeface.BOLD)
|
||||
|
||||
// TextView : number of following
|
||||
val nbFollowing = view.findViewById<TextView>(R.id.nbFollowing)
|
||||
nbFollowing.text = account.following_count.toString()
|
||||
val nbFollowing = view.findViewById<TextView>(R.id.nbFollowingTextView)
|
||||
nbFollowing.text = account.following_count.toString() + "\nFollowing"
|
||||
nbFollowing.setTypeface(null, Typeface.BOLD)
|
||||
}
|
||||
|
||||
private fun onClickEditButton() {
|
||||
val url = "${preferences.getString("domain", "")}/settings/home"
|
||||
|
||||
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||
if(activity != null && browserIntent.resolveActivity(activity!!.packageManager) != null) {
|
||||
startActivity(browserIntent)
|
||||
} else {
|
||||
val text = "Cannot open this link"
|
||||
Log.e("ProfileFragment", text)
|
||||
}
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@
|
||||
tools:openDrawer="start"
|
||||
tools:context="com.h.pixeldroid.MainActivity">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
123
app/src/main/res/layout/fragment_my_profile.xml
Normal file
123
app/src/main/res/layout/fragment_my_profile.xml
Normal file
@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout 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"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".fragments.MyProfileFragment">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/profilePictureImageView"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="120dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="24dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:srcCompat="@tools:sample/avatars" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/linearLayout"
|
||||
android:layout_width="230dp"
|
||||
android:layout_height="120dp"
|
||||
android:layout_marginTop="24dp"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/profilePictureImageView"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/nbPostsTextView"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:text="-\nPosts" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/nbFollowersTextView"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="120dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:text="-\nFollowers" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/nbFollowingTextView"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="120dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:text="-\nFollowing" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/accountNameTextView"
|
||||
android:layout_width="156dp"
|
||||
android:layout_height="22dp"
|
||||
android:layout_marginTop="15dp"
|
||||
android:text="No Username"
|
||||
app:layout_constraintStart_toStartOf="@+id/profilePictureImageView"
|
||||
app:layout_constraintTop_toBottomOf="@+id/profilePictureImageView" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/descriptionTextView"
|
||||
android:layout_width="348dp"
|
||||
android:layout_height="85dp"
|
||||
android:layout_marginTop="14dp"
|
||||
android:autoSizeMaxTextSize="300sp"
|
||||
android:autoSizeMinTextSize="2sp"
|
||||
android:autoSizeStepGranularity="2sp"
|
||||
android:autoSizeTextType="uniform"
|
||||
app:layout_constraintStart_toStartOf="@+id/accountNameTextView"
|
||||
app:layout_constraintTop_toBottomOf="@+id/accountNameTextView" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/editButton"
|
||||
android:layout_width="350dp"
|
||||
android:layout_height="37dp"
|
||||
android:layout_marginTop="14dp"
|
||||
android:gravity="center"
|
||||
android:text="Edit profile"
|
||||
android:background="@color/colorPrimary"
|
||||
android:textColor="@color/cardview_light_background"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/descriptionTextView" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="409dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginTop="340dp"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/postsButton"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@color/cardview_shadow_end_color"
|
||||
android:gravity="right"
|
||||
app:srcCompat="@android:drawable/ic_dialog_dialer" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/collectionButton"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@color/cardview_shadow_end_color"
|
||||
android:gravity="left"
|
||||
app:srcCompat="@android:drawable/ic_menu_gallery" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</FrameLayout>
|
@ -1,129 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/profile_main_container"
|
||||
tools:context=".fragments.ProfileFragment">
|
||||
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/profilePicture"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="120dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="24dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:srcCompat="@tools:sample/avatars" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/nbFollowing"
|
||||
android:layout_width="38dp"
|
||||
android:layout_height="26dp"
|
||||
android:layout_marginTop="52dp"
|
||||
android:layout_marginEnd="36dp"
|
||||
android:text="N/A"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/nbPosts"
|
||||
android:layout_width="39dp"
|
||||
android:layout_height="27dp"
|
||||
android:layout_marginStart="152dp"
|
||||
android:layout_marginTop="52dp"
|
||||
android:text="N/A"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/posts"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="Posts"
|
||||
app:layout_constraintEnd_toEndOf="@+id/nbPosts"
|
||||
app:layout_constraintStart_toStartOf="@+id/nbPosts"
|
||||
app:layout_constraintTop_toBottomOf="@+id/nbPosts" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/followers"
|
||||
android:layout_width="65dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="Followers"
|
||||
app:layout_constraintEnd_toEndOf="@+id/nbFollowers"
|
||||
app:layout_constraintStart_toStartOf="@+id/nbFollowers"
|
||||
app:layout_constraintTop_toBottomOf="@+id/nbFollowers" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/following"
|
||||
android:layout_width="65dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="Following"
|
||||
app:layout_constraintEnd_toEndOf="@+id/nbFollowing"
|
||||
app:layout_constraintStart_toStartOf="@+id/nbFollowing"
|
||||
app:layout_constraintTop_toBottomOf="@+id/nbFollowing" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/nbFollowers"
|
||||
android:layout_width="39dp"
|
||||
android:layout_height="27dp"
|
||||
android:layout_marginTop="52dp"
|
||||
android:text="N/A"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.669"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/accountName"
|
||||
android:layout_width="156dp"
|
||||
android:layout_height="22dp"
|
||||
android:layout_marginTop="15dp"
|
||||
android:text="@string/no_username"
|
||||
app:layout_constraintStart_toStartOf="@+id/profilePicture"
|
||||
app:layout_constraintTop_toBottomOf="@+id/profilePicture" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="348dp"
|
||||
android:layout_height="85dp"
|
||||
android:layout_marginTop="14dp"
|
||||
app:layout_constraintStart_toStartOf="@+id/accountName"
|
||||
app:layout_constraintTop_toBottomOf="@+id/accountName" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/followButton"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="38dp"
|
||||
android:layout_marginTop="14dp"
|
||||
android:text="Follow"
|
||||
app:layout_constraintStart_toStartOf="@+id/description"
|
||||
app:layout_constraintTop_toBottomOf="@+id/description" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/postsButton"
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="42dp"
|
||||
android:layout_marginStart="152dp"
|
||||
android:layout_marginTop="20dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/followButton"
|
||||
app:srcCompat="@android:drawable/ic_dialog_dialer" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/collectionButton"
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="42dp"
|
||||
android:layout_marginStart="4dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toEndOf="@+id/postsButton"
|
||||
app:layout_constraintTop_toTopOf="@+id/postsButton"
|
||||
app:srcCompat="@android:drawable/ic_menu_gallery" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
Loading…
x
Reference in New Issue
Block a user