Implements swipe motion & fragmentalize (#41)
* 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 * refactor settings drawer tests * added more tests and refactored some files * added animations to the sliding of the swipe motion
This commit is contained in:
parent
f124af3800
commit
de314dc9de
@ -71,6 +71,7 @@ dependencies {
|
|||||||
}
|
}
|
||||||
implementation "com.github.bumptech.glide:okhttp-integration:4.11.0"
|
implementation "com.github.bumptech.glide:okhttp-integration:4.11.0"
|
||||||
|
|
||||||
|
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||||
testImplementation "com.github.tomakehurst:wiremock-jre8:2.26.3"
|
testImplementation "com.github.tomakehurst:wiremock-jre8:2.26.3"
|
||||||
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
|
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
|
||||||
testImplementation 'junit:junit:4.13'
|
testImplementation 'junit:junit:4.13'
|
||||||
|
25
app/src/androidTest/java/com/h/pixeldroid/BottomMenuTest.kt
Normal file
25
app/src/androidTest/java/com/h/pixeldroid/BottomMenuTest.kt
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package com.h.pixeldroid
|
||||||
|
|
||||||
|
import androidx.test.espresso.Espresso.onView
|
||||||
|
import androidx.test.espresso.action.ViewActions.click
|
||||||
|
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||||
|
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||||
|
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||||
|
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class BottomMenuTest {
|
||||||
|
@get:Rule
|
||||||
|
var activityRule: ActivityScenarioRule<MainActivity>
|
||||||
|
= ActivityScenarioRule(MainActivity::class.java)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testFollowersTextView() {
|
||||||
|
onView(withId(R.id.activity_main_account_btn)).perform(click())
|
||||||
|
onView(withId(R.id.profile_main_container)).check(matches(isDisplayed()))
|
||||||
|
}
|
||||||
|
}
|
@ -2,12 +2,10 @@ package com.h.pixeldroid
|
|||||||
|
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
import org.junit.Assert.*
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instrumented test, which will execute on an Android device.
|
* Instrumented test, which will execute on an Android device.
|
||||||
*
|
*
|
||||||
|
@ -12,11 +12,15 @@ import androidx.test.espresso.intent.Intents.intended
|
|||||||
import androidx.test.espresso.intent.matcher.IntentMatchers.hasAction
|
import androidx.test.espresso.intent.matcher.IntentMatchers.hasAction
|
||||||
import androidx.test.espresso.intent.matcher.IntentMatchers.hasDataString
|
import androidx.test.espresso.intent.matcher.IntentMatchers.hasDataString
|
||||||
import androidx.test.espresso.intent.rule.IntentsTestRule
|
import androidx.test.espresso.intent.rule.IntentsTestRule
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.*
|
import androidx.test.espresso.matcher.ViewMatchers.hasErrorText
|
||||||
|
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.rules.ActivityScenarioRule
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.rule.ActivityTestRule
|
import androidx.test.rule.ActivityTestRule
|
||||||
import org.hamcrest.CoreMatchers.*
|
import org.hamcrest.CoreMatchers.allOf
|
||||||
|
import org.hamcrest.CoreMatchers.anyOf
|
||||||
|
import org.hamcrest.CoreMatchers.containsString
|
||||||
import org.hamcrest.Matcher
|
import org.hamcrest.Matcher
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
@ -39,26 +43,27 @@ class LoginInstrumentedTest {
|
|||||||
fun clickConnect() {
|
fun clickConnect() {
|
||||||
onView(withId(R.id.connect_instance_button)).check(matches(withText("Connect")))
|
onView(withId(R.id.connect_instance_button)).check(matches(withText("Connect")))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun invalidURL() {
|
fun invalidURL() {
|
||||||
onView(withId(R.id.editText)).perform(ViewActions.replaceText("/jdi"), ViewActions.closeSoftKeyboard())
|
onView(withId(R.id.editText)).perform(ViewActions.replaceText("/jdi"), ViewActions.closeSoftKeyboard())
|
||||||
onView(withId(R.id.connect_instance_button)).perform(click())
|
onView(withId(R.id.connect_instance_button)).perform(click())
|
||||||
onView(withId(R.id.editText)).check(matches(hasErrorText("Invalid domain")))
|
onView(withId(R.id.editText)).check(matches(hasErrorText("Invalid domain")))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun notPixelfedInstance() {
|
fun notPixelfedInstance() {
|
||||||
onView(withId(R.id.editText)).perform(ViewActions.replaceText("localhost"), ViewActions.closeSoftKeyboard())
|
onView(withId(R.id.editText)).perform(ViewActions.replaceText("localhost"), ViewActions.closeSoftKeyboard())
|
||||||
onView(withId(R.id.connect_instance_button)).perform(click())
|
onView(withId(R.id.connect_instance_button)).perform(click())
|
||||||
onView(withId(R.id.editText)).check(matches(hasErrorText("Could not register the application with this server")))
|
onView(withId(R.id.editText)).check(matches(hasErrorText("Could not register the application with this server")))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
class LoginCheckIntent {
|
class LoginCheckIntent {
|
||||||
@get:Rule
|
@get:Rule
|
||||||
val intentsTestRule = IntentsTestRule(LoginActivity::class.java)
|
val intentsTestRule = IntentsTestRule(LoginActivity::class.java)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun launchesIntent() {
|
fun launchesIntent() {
|
||||||
val expectedIntent: Matcher<Intent> = allOf(
|
val expectedIntent: Matcher<Intent> = allOf(
|
||||||
@ -75,6 +80,7 @@ class LoginCheckIntent {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
class AfterIntent {
|
class AfterIntent {
|
||||||
|
|
||||||
@ -87,6 +93,7 @@ class AfterIntent {
|
|||||||
val intent = Intent(ACTION_VIEW, Uri.parse("oauth2redirect://com.h.pixeldroid?code=sdfdqsf"))
|
val intent = Intent(ACTION_VIEW, Uri.parse("oauth2redirect://com.h.pixeldroid?code=sdfdqsf"))
|
||||||
launchedActivity = rule.launchActivity(intent)
|
launchedActivity = rule.launchActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun usesIntent() {
|
fun usesIntent() {
|
||||||
|
|
||||||
|
@ -3,15 +3,16 @@ package com.h.pixeldroid
|
|||||||
import androidx.test.espresso.Espresso.onView
|
import androidx.test.espresso.Espresso.onView
|
||||||
import androidx.test.espresso.action.ViewActions.click
|
import androidx.test.espresso.action.ViewActions.click
|
||||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.*
|
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.rules.ActivityScenarioRule
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import org.hamcrest.Matchers.not
|
import org.hamcrest.Matchers.not
|
||||||
|
import org.junit.Before
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import java.lang.Thread.sleep
|
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
class ProfileTest {
|
class ProfileTest {
|
||||||
@ -19,10 +20,14 @@ class ProfileTest {
|
|||||||
var activityRule: ActivityScenarioRule<MainActivity>
|
var activityRule: ActivityScenarioRule<MainActivity>
|
||||||
= ActivityScenarioRule(MainActivity::class.java)
|
= ActivityScenarioRule(MainActivity::class.java)
|
||||||
|
|
||||||
@Test
|
@Before
|
||||||
fun testFollowersTextView() {
|
fun openProfileFragment() {
|
||||||
onView(withId(R.id.button)).perform(click())
|
onView(withId(R.id.activity_main_account_btn)).perform(click())
|
||||||
onView(withId(R.id.followers)).check(matches(withText("Followers")))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun randomUsernameCorrectlyLoadedTest() {
|
||||||
|
Thread.sleep(5000) // wait for the username to load (to modify once we know how)
|
||||||
|
onView(withId(R.id.accountName)).check(matches(not(withText(R.string.no_username))))
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,16 +1,14 @@
|
|||||||
package com.h.pixeldroid
|
package com.h.pixeldroid
|
||||||
|
|
||||||
import android.view.Gravity
|
|
||||||
import androidx.test.espresso.Espresso.onView
|
import androidx.test.espresso.Espresso.onView
|
||||||
import androidx.test.espresso.Espresso.pressBack
|
|
||||||
import androidx.test.espresso.action.ViewActions
|
|
||||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||||
import androidx.test.espresso.contrib.DrawerActions
|
import androidx.test.espresso.contrib.DrawerActions
|
||||||
import androidx.test.espresso.contrib.DrawerMatchers.isClosed
|
|
||||||
import androidx.test.espresso.contrib.NavigationViewActions
|
import androidx.test.espresso.contrib.NavigationViewActions
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.*
|
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||||
|
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||||
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import org.junit.Before
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
@ -22,47 +20,25 @@ class SettingsTest {
|
|||||||
var activityRule: ActivityScenarioRule<MainActivity>
|
var activityRule: ActivityScenarioRule<MainActivity>
|
||||||
= ActivityScenarioRule(MainActivity::class.java)
|
= ActivityScenarioRule(MainActivity::class.java)
|
||||||
|
|
||||||
@Test
|
@Before
|
||||||
fun testDrawerSettingsButton() {
|
fun openDrawer() {
|
||||||
// Open Drawer to click on navigation.
|
onView(withId(R.id.drawer_layout)).perform(DrawerActions.open())
|
||||||
onView(withId(R.id.drawer_layout))
|
|
||||||
.check(matches(isClosed(Gravity.LEFT))) // Left Drawer should be closed.
|
|
||||||
.perform(DrawerActions.open()); // Open Drawer
|
|
||||||
|
|
||||||
// Start the screen of the activity.
|
|
||||||
onView(withId(R.id.nav_view)).perform(NavigationViewActions.navigateTo(R.id.nav_settings))
|
|
||||||
|
|
||||||
// Check that settings activity was opened.
|
|
||||||
onView(withText(R.string.signature_title)).check(matches(isDisplayed()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testDrawerProfileButton() {
|
fun myProfileButtonTest() {
|
||||||
// Open Drawer to click on navigation.
|
|
||||||
onView(withId(R.id.drawer_layout))
|
|
||||||
.check(matches(isClosed(Gravity.LEFT))) // Left Drawer should be closed.
|
|
||||||
.perform(DrawerActions.open()); // Open Drawer
|
|
||||||
|
|
||||||
// Start the screen of the activity.
|
|
||||||
onView(withId(R.id.nav_view)).perform(NavigationViewActions.navigateTo(R.id.nav_account))
|
onView(withId(R.id.nav_view)).perform(NavigationViewActions.navigateTo(R.id.nav_account))
|
||||||
|
onView(withId(R.id.profile_main_container)).check(matches(isDisplayed()))
|
||||||
// Check that profile activity was opened.
|
|
||||||
onView(withId(R.id.posts)).check(matches(withText("Posts")))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testOnBackPressed() {
|
fun settingsButtonTest() {
|
||||||
// Open Drawer to click on navigation.
|
|
||||||
onView(withId(R.id.drawer_layout))
|
|
||||||
.check(matches(isClosed(Gravity.LEFT))) // Left Drawer should be closed.
|
|
||||||
.perform(DrawerActions.open()); // Open Drawer
|
|
||||||
|
|
||||||
// Start the screen of your activity.
|
|
||||||
onView(withId(R.id.nav_view)).perform(NavigationViewActions.navigateTo(R.id.nav_settings))
|
onView(withId(R.id.nav_view)).perform(NavigationViewActions.navigateTo(R.id.nav_settings))
|
||||||
|
onView(withId(R.id.settings)).check(matches(isDisplayed()))
|
||||||
|
}
|
||||||
|
|
||||||
onView(withId(R.id.settings)).perform(ViewActions.pressBack())
|
@Test
|
||||||
|
fun accessibilityButtonTest() {
|
||||||
// Check that profile activity was opened.
|
// TODO if some accessibility view is added
|
||||||
onView(withId(R.id.button_start_login)).check(matches(withText("start login")))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
33
app/src/androidTest/java/com/h/pixeldroid/SwipeTest.kt
Normal file
33
app/src/androidTest/java/com/h/pixeldroid/SwipeTest.kt
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package com.h.pixeldroid
|
||||||
|
|
||||||
|
import androidx.test.espresso.Espresso.onView
|
||||||
|
import androidx.test.espresso.action.ViewActions.swipeLeft
|
||||||
|
import androidx.test.espresso.action.ViewActions.swipeRight
|
||||||
|
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||||
|
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||||
|
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||||
|
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class SwipeTest {
|
||||||
|
@get:Rule
|
||||||
|
var activityRule: ActivityScenarioRule<MainActivity>
|
||||||
|
= ActivityScenarioRule(MainActivity::class.java)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun swipingRightOnHomepageShowsSettings() {
|
||||||
|
onView(withId(R.id.main_linear_layout)).perform(swipeRight())
|
||||||
|
onView(withId(R.id.nav_view)).check(matches(isDisplayed()))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun swipeLeftOnHomePageShowsProfile() {
|
||||||
|
// to modify when we add more tabs
|
||||||
|
onView(withId(R.id.main_linear_layout)).perform(swipeLeft())
|
||||||
|
onView(withId(R.id.profile_main_container)).check(matches(isDisplayed()))
|
||||||
|
}
|
||||||
|
}
|
@ -41,11 +41,6 @@
|
|||||||
android:scheme="@string/auth_scheme" />
|
android:scheme="@string/auth_scheme" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".ProfileActivity">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value=".MainActivity"/>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ import android.content.Intent
|
|||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.browser.customtabs.CustomTabsIntent
|
import androidx.browser.customtabs.CustomTabsIntent
|
||||||
import com.h.pixeldroid.api.PixelfedAPI
|
import com.h.pixeldroid.api.PixelfedAPI
|
||||||
|
@ -3,13 +3,18 @@ package com.h.pixeldroid
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
|
import android.widget.ImageButton
|
||||||
|
import android.widget.LinearLayout
|
||||||
import androidx.annotation.NonNull
|
import androidx.annotation.NonNull
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.GravityCompat
|
import androidx.core.view.GravityCompat
|
||||||
import androidx.drawerlayout.widget.DrawerLayout
|
import androidx.drawerlayout.widget.DrawerLayout
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
import com.google.android.material.navigation.NavigationView
|
import com.google.android.material.navigation.NavigationView
|
||||||
|
import com.h.pixeldroid.fragments.HomeFragment
|
||||||
|
import com.h.pixeldroid.fragments.ProfileFragment
|
||||||
|
import com.h.pixeldroid.motions.OnSwipeListener
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
|
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
|
||||||
|
|
||||||
@ -19,20 +24,49 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
|
|||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
|
|
||||||
|
val mainLinearLayout : LinearLayout = findViewById(R.id.main_linear_layout)
|
||||||
|
val homepageButton : ImageButton = findViewById(R.id.activity_main_home_btn)
|
||||||
|
val accountButton : ImageButton = findViewById(R.id.activity_main_account_btn)
|
||||||
|
|
||||||
|
homepageButton.setOnClickListener {
|
||||||
|
launchFragment(HomeFragment())
|
||||||
|
}
|
||||||
|
accountButton.setOnClickListener {
|
||||||
|
launchFragment(ProfileFragment())
|
||||||
|
}
|
||||||
|
|
||||||
// Setup the drawer
|
// Setup the drawer
|
||||||
drawerLayout = findViewById(R.id.drawer_layout)
|
drawerLayout = findViewById(R.id.drawer_layout)
|
||||||
val navigationView: NavigationView = findViewById(R.id.nav_view)
|
val navigationView: NavigationView = findViewById(R.id.nav_view)
|
||||||
navigationView.setNavigationItemSelectedListener(this)
|
navigationView.setNavigationItemSelectedListener(this)
|
||||||
|
|
||||||
val buttonLogin = findViewById<Button>(R.id.button_start_login)
|
val onSwipeListener = object: OnSwipeListener(this) {
|
||||||
buttonLogin.setOnClickListener((View.OnClickListener {
|
override fun onSwipeRight() = swipeRight()
|
||||||
val intent = Intent(this, LoginActivity::class.java)
|
override fun onSwipeLeft() = swipeLeft()
|
||||||
startActivity(intent) }))
|
}
|
||||||
|
mainLinearLayout.setOnTouchListener(onSwipeListener)
|
||||||
|
|
||||||
val button = findViewById<Button>(R.id.button)
|
// default fragment that displays when we open the app
|
||||||
button.setOnClickListener((View.OnClickListener {
|
launchFragment(HomeFragment())
|
||||||
val intent = Intent(this, ProfileActivity::class.java)
|
}
|
||||||
startActivity(intent) }))
|
|
||||||
|
private fun swipeRight() {
|
||||||
|
// TODO: correctly switch between tabs
|
||||||
|
drawerLayout.openDrawer(GravityCompat.START)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun swipeLeft() {
|
||||||
|
// TODO: correctly switch between tabs
|
||||||
|
supportFragmentManager.beginTransaction()
|
||||||
|
.setCustomAnimations(R.anim.slide_from_right, R.anim.slide_to_left)
|
||||||
|
.replace(R.id.fragment_container, ProfileFragment()).commit()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Launches the given fragment and put it as the current "activity"
|
||||||
|
*/
|
||||||
|
private fun launchFragment(fragment: Fragment) {
|
||||||
|
supportFragmentManager.beginTransaction().replace(R.id.fragment_container, fragment).commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -41,7 +75,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
|
|||||||
override fun onNavigationItemSelected(@NonNull item: MenuItem): Boolean {
|
override fun onNavigationItemSelected(@NonNull item: MenuItem): Boolean {
|
||||||
when (item.itemId){
|
when (item.itemId){
|
||||||
R.id.nav_settings -> launchActivity(SettingsActivity())
|
R.id.nav_settings -> launchActivity(SettingsActivity())
|
||||||
R.id.nav_account -> launchActivity(ProfileActivity())
|
R.id.nav_account -> launchFragment(ProfileFragment())
|
||||||
}
|
}
|
||||||
|
|
||||||
drawerLayout.closeDrawer(GravityCompat.START)
|
drawerLayout.closeDrawer(GravityCompat.START)
|
||||||
|
29
app/src/main/java/com/h/pixeldroid/fragments/HomeFragment.kt
Normal file
29
app/src/main/java/com/h/pixeldroid/fragments/HomeFragment.kt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package com.h.pixeldroid.fragments
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.Button
|
||||||
|
import com.h.pixeldroid.LoginActivity
|
||||||
|
|
||||||
|
import com.h.pixeldroid.R
|
||||||
|
|
||||||
|
|
||||||
|
class HomeFragment : Fragment() {
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View? {
|
||||||
|
val view: View = inflater.inflate(R.layout.fragment_home, container, false)
|
||||||
|
|
||||||
|
val loginButton: Button = view.findViewById(R.id.button_start_login)
|
||||||
|
loginButton.setOnClickListener {
|
||||||
|
startActivity(Intent(view.context, LoginActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
return view
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,20 @@
|
|||||||
package com.h.pixeldroid
|
package com.h.pixeldroid.fragments
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
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.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
|
import com.h.pixeldroid.LoginActivity
|
||||||
|
|
||||||
|
import com.h.pixeldroid.R
|
||||||
import com.h.pixeldroid.api.PixelfedAPI
|
import com.h.pixeldroid.api.PixelfedAPI
|
||||||
import com.h.pixeldroid.objects.Account
|
import com.h.pixeldroid.objects.Account
|
||||||
import com.h.pixeldroid.objects.Status
|
import com.h.pixeldroid.objects.Status
|
||||||
@ -14,18 +22,19 @@ import retrofit2.Call
|
|||||||
import retrofit2.Callback
|
import retrofit2.Callback
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
|
|
||||||
class ProfileActivity : AppCompatActivity() {
|
const val BASE_URL = "https://pixelfed.de/"
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
class ProfileFragment : Fragment() {
|
||||||
super.onCreate(savedInstanceState)
|
override fun onCreateView(
|
||||||
setContentView(R.layout.activity_profile)
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View? {
|
||||||
|
val view: View = inflater.inflate(R.layout.fragment_profile, container, false)
|
||||||
|
|
||||||
var statuses: ArrayList<Status>? = null
|
var statuses: ArrayList<Status>?
|
||||||
val BASE_URL = "https://pixelfed.de/"
|
|
||||||
|
|
||||||
val pixelfedAPI = PixelfedAPI.create(BASE_URL)
|
val pixelfedAPI = PixelfedAPI.create(BASE_URL)
|
||||||
|
|
||||||
|
|
||||||
pixelfedAPI.timelinePublic(null, null, null, null, null)
|
pixelfedAPI.timelinePublic(null, null, null, null, null)
|
||||||
.enqueue(object : Callback<List<Status>> {
|
.enqueue(object : Callback<List<Status>> {
|
||||||
override fun onResponse(call: Call<List<Status>>, response: Response<List<Status>>) {
|
override fun onResponse(call: Call<List<Status>>, response: Response<List<Status>>) {
|
||||||
@ -36,7 +45,7 @@ class ProfileActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
val account = statuses!![0].account
|
val account = statuses!![0].account
|
||||||
|
|
||||||
setContent(account)
|
setContent(view, account)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -47,33 +56,34 @@ class ProfileActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
return view
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setContent(account: Account) {
|
private fun setContent(view: View, account: Account) {
|
||||||
// ImageView : profile picture
|
// ImageView : profile picture
|
||||||
val profilePicture = findViewById<ImageView>(R.id.profilePicture)
|
val profilePicture = view.findViewById<ImageView>(R.id.profilePicture)
|
||||||
Glide.with(applicationContext).load(account.avatar).into(profilePicture)
|
Glide.with(view.context.applicationContext).load(account.avatar).into(profilePicture)
|
||||||
|
|
||||||
// TextView : description / bio
|
// TextView : description / bio
|
||||||
val description = findViewById<TextView>(R.id.description)
|
val description = view.findViewById<TextView>(R.id.description)
|
||||||
description.text = account.note
|
description.text = account.note
|
||||||
|
|
||||||
// TextView : account name
|
// TextView : account name
|
||||||
val accountName = findViewById<TextView>(R.id.accountName)
|
val accountName = view.findViewById<TextView>(R.id.accountName)
|
||||||
accountName.text = account.username
|
accountName.text = account.username
|
||||||
|
|
||||||
// TextView : number of posts
|
// TextView : number of posts
|
||||||
val nbPosts = findViewById<TextView>(R.id.nbPosts)
|
val nbPosts = view.findViewById<TextView>(R.id.nbPosts)
|
||||||
nbPosts.text = account.statuses_count.toString()
|
nbPosts.text = account.statuses_count.toString()
|
||||||
nbPosts.setTypeface(null, Typeface.BOLD)
|
nbPosts.setTypeface(null, Typeface.BOLD)
|
||||||
|
|
||||||
// TextView : number of followers
|
// TextView : number of followers
|
||||||
val nbFollowers = findViewById<TextView>(R.id.nbFollowers)
|
val nbFollowers = view.findViewById<TextView>(R.id.nbFollowers)
|
||||||
nbFollowers.text = account.followers_count.toString()
|
nbFollowers.text = account.followers_count.toString()
|
||||||
nbFollowers.setTypeface(null, Typeface.BOLD)
|
nbFollowers.setTypeface(null, Typeface.BOLD)
|
||||||
|
|
||||||
// TextView : number of following
|
// TextView : number of following
|
||||||
val nbFollowing = findViewById<TextView>(R.id.nbFollowing)
|
val nbFollowing = view.findViewById<TextView>(R.id.nbFollowing)
|
||||||
nbFollowing.text = account.following_count.toString()
|
nbFollowing.text = account.following_count.toString()
|
||||||
nbFollowing.setTypeface(null, Typeface.BOLD)
|
nbFollowing.setTypeface(null, Typeface.BOLD)
|
||||||
}
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
package com.h.pixeldroid.motions
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.GestureDetector
|
||||||
|
import android.view.GestureDetector.SimpleOnGestureListener
|
||||||
|
import android.view.MotionEvent
|
||||||
|
import android.view.View
|
||||||
|
import android.view.View.OnTouchListener
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
const val SWIPE_DISTANCE_THRESHOLD: Int = 100
|
||||||
|
const val SWIPE_VELOCITY_THRESHOLD: Int = 100
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detects left and right swipes across a view.
|
||||||
|
*
|
||||||
|
* inspired from https://stackoverflow.com/questions/4139288/android-how-to-handle-right-to-left-swipe-gestures
|
||||||
|
*/
|
||||||
|
open class OnSwipeListener(context: Context?) : OnTouchListener {
|
||||||
|
|
||||||
|
private val gestureDetector: GestureDetector = GestureDetector(context, GestureListener())
|
||||||
|
|
||||||
|
override fun onTouch(v: View?, event: MotionEvent?): Boolean =
|
||||||
|
gestureDetector.onTouchEvent(event)
|
||||||
|
|
||||||
|
// redefining gesture listener to call our custom functions
|
||||||
|
private inner class GestureListener : SimpleOnGestureListener() {
|
||||||
|
|
||||||
|
override fun onDown(e: MotionEvent): Boolean = true
|
||||||
|
|
||||||
|
override fun onFling(
|
||||||
|
e1: MotionEvent,
|
||||||
|
e2: MotionEvent,
|
||||||
|
velocityX: Float,
|
||||||
|
velocityY: Float
|
||||||
|
): Boolean {
|
||||||
|
val distanceX = e2.x - e1.x
|
||||||
|
val distanceY = e2.y - e1.y
|
||||||
|
if (abs(distanceX) > abs(distanceY) // swipe on the side and not up or down
|
||||||
|
&& abs(distanceX) > SWIPE_DISTANCE_THRESHOLD
|
||||||
|
&& abs(velocityX) > SWIPE_VELOCITY_THRESHOLD
|
||||||
|
) {
|
||||||
|
if (distanceX > 0) onSwipeRight() else onSwipeLeft()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun onSwipeLeft() {}
|
||||||
|
|
||||||
|
open fun onSwipeRight() {}
|
||||||
|
}
|
8
app/src/main/res/anim/slide_from_left.xml
Normal file
8
app/src/main/res/anim/slide_from_left.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<translate
|
||||||
|
android:fromXDelta="-100%p"
|
||||||
|
android:toXDelta="0"
|
||||||
|
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
|
||||||
|
android:duration="@integer/swipe_animation_duration"/>
|
||||||
|
</set>
|
8
app/src/main/res/anim/slide_from_right.xml
Normal file
8
app/src/main/res/anim/slide_from_right.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<translate
|
||||||
|
android:fromXDelta="100%p"
|
||||||
|
android:toXDelta="0"
|
||||||
|
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
|
||||||
|
android:duration="@integer/swipe_animation_duration"/>
|
||||||
|
</set>
|
8
app/src/main/res/anim/slide_to_left.xml
Normal file
8
app/src/main/res/anim/slide_to_left.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<translate
|
||||||
|
android:fromXDelta="0"
|
||||||
|
android:toXDelta="-100%p"
|
||||||
|
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
|
||||||
|
android:duration="@integer/swipe_animation_duration"/>
|
||||||
|
</set>
|
8
app/src/main/res/anim/slide_to_right.xml
Normal file
8
app/src/main/res/anim/slide_to_right.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<translate
|
||||||
|
android:fromXDelta="0"
|
||||||
|
android:toXDelta="100%p"
|
||||||
|
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
|
||||||
|
android:duration="@integer/swipe_animation_duration"/>
|
||||||
|
</set>
|
5
app/src/main/res/drawable/ic_home_white_24dp.xml
Normal file
5
app/src/main/res/drawable/ic_home_white_24dp.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||||
|
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="#FF000000" android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z"/>
|
||||||
|
</vector>
|
5
app/src/main/res/drawable/ic_person_white_24dp.xml
Normal file
5
app/src/main/res/drawable/ic_person_white_24dp.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||||
|
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="#FF000000" android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/>
|
||||||
|
</vector>
|
6
app/src/main/res/drawable/ic_photo_camera_white_24dp.xml
Normal file
6
app/src/main/res/drawable/ic_photo_camera_white_24dp.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||||
|
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="#FF000000" android:pathData="M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0"/>
|
||||||
|
<path android:fillColor="#FF000000" android:pathData="M9,2L7.17,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2L9,2zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z"/>
|
||||||
|
</vector>
|
5
app/src/main/res/drawable/ic_search_white_24dp.xml
Normal file
5
app/src/main/res/drawable/ic_search_white_24dp.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||||
|
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="#FF000000" android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
|
||||||
|
</vector>
|
5
app/src/main/res/drawable/ic_star_white_24dp.xml
Normal file
5
app/src/main/res/drawable/ic_star_white_24dp.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||||
|
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="#FF000000" android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z"/>
|
||||||
|
</vector>
|
@ -7,28 +7,72 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
tools:openDrawer="start"
|
tools:openDrawer="start"
|
||||||
tools:context=".MainActivity">
|
tools:context="com.h.pixeldroid.MainActivity">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
tools:layout_editor_absoluteX="67dp"
|
android:id="@+id/main_linear_layout">
|
||||||
tools:layout_editor_absoluteY="299dp">
|
|
||||||
|
|
||||||
<Button
|
<FrameLayout
|
||||||
android:id="@+id/button_start_login"
|
android:id="@+id/fragment_container"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="0dp"
|
||||||
android:layout_marginTop="80dp"
|
android:layout_weight="1" />
|
||||||
android:text="start login" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/button"
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Show a profile" />
|
android:background="@color/colorPrimary"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/activity_main_home_btn"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:padding="10dp"
|
||||||
|
app:srcCompat="@drawable/ic_home_white_24dp" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/activity_main_search_btn"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
app:srcCompat="@drawable/ic_search_white_24dp" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/activity_main_camera_btn"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
app:srcCompat="@drawable/ic_photo_camera_white_24dp" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/activity_main_favorite_btn"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
app:srcCompat="@drawable/ic_star_white_24dp" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/activity_main_account_btn"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
app:srcCompat="@drawable/ic_person_white_24dp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<com.google.android.material.navigation.NavigationView
|
<com.google.android.material.navigation.NavigationView
|
||||||
@ -40,6 +84,5 @@
|
|||||||
app:headerLayout="@layout/nav_header"
|
app:headerLayout="@layout/nav_header"
|
||||||
app:menu="@menu/activity_main_drawer" />
|
app:menu="@menu/activity_main_drawer" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</androidx.drawerlayout.widget.DrawerLayout>
|
</androidx.drawerlayout.widget.DrawerLayout>
|
||||||
|
|
||||||
|
23
app/src/main/res/layout/fragment_home.xml
Normal file
23
app/src/main/res/layout/fragment_home.xml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".fragments.HomeFragment">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/button_start_login"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:text="@string/start_login" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</FrameLayout>
|
@ -4,7 +4,8 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".ProfileActivity">
|
android:id="@+id/profile_main_container"
|
||||||
|
tools:context=".fragments.ProfileFragment">
|
||||||
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
@ -27,16 +28,6 @@
|
|||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="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
|
<TextView
|
||||||
android:id="@+id/nbPosts"
|
android:id="@+id/nbPosts"
|
||||||
android:layout_width="39dp"
|
android:layout_width="39dp"
|
||||||
@ -47,6 +38,16 @@
|
|||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="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
|
<TextView
|
||||||
android:id="@+id/followers"
|
android:id="@+id/followers"
|
||||||
android:layout_width="65dp"
|
android:layout_width="65dp"
|
||||||
@ -83,7 +84,7 @@
|
|||||||
android:layout_width="156dp"
|
android:layout_width="156dp"
|
||||||
android:layout_height="22dp"
|
android:layout_height="22dp"
|
||||||
android:layout_marginTop="15dp"
|
android:layout_marginTop="15dp"
|
||||||
android:text="No Username"
|
android:text="@string/no_username"
|
||||||
app:layout_constraintStart_toStartOf="@+id/profilePicture"
|
app:layout_constraintStart_toStartOf="@+id/profilePicture"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/profilePicture" />
|
app:layout_constraintTop_toBottomOf="@+id/profilePicture" />
|
||||||
|
|
4
app/src/main/res/values/integers.xml
Normal file
4
app/src/main/res/values/integers.xml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<integer name="swipe_animation_duration">300</integer>
|
||||||
|
</resources>
|
@ -53,4 +53,9 @@
|
|||||||
<string name="attachment_summary_on">Automatically download attachments for incoming emails
|
<string name="attachment_summary_on">Automatically download attachments for incoming emails
|
||||||
</string>
|
</string>
|
||||||
<string name="attachment_summary_off">Only download attachments when manually requested</string>
|
<string name="attachment_summary_off">Only download attachments when manually requested</string>
|
||||||
|
|
||||||
|
<!-- TODO: Remove or change this placeholder text -->
|
||||||
|
<string name="hello_blank_fragment">Hello blank fragment</string>
|
||||||
|
<string name="start_login">Start Login</string>
|
||||||
|
<string name="no_username">No Username</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.h.pixeldroid
|
||||||
|
|
||||||
|
import com.h.pixeldroid.motions.OnSwipeListener
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class OnSwipeListenerUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun undefinedSwipeRightDoesNothingTest() {
|
||||||
|
val swipeListener = OnSwipeListener(null)
|
||||||
|
assertEquals(Unit, swipeListener.onSwipeRight())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun undefinedSwipeLeftDoesNothingTest() {
|
||||||
|
val swipeListener = OnSwipeListener(null)
|
||||||
|
assertEquals(Unit, swipeListener.onSwipeLeft())
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user