add swiperefreshlayout
This commit is contained in:
parent
b01a859741
commit
a4a60c596d
10 changed files with 191 additions and 25 deletions
|
@ -40,11 +40,13 @@ dependencies {
|
|||
implementation 'androidx.core:core-ktx:1.3.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
implementation "androidx.drawerlayout:drawerlayout:1.1.0"
|
||||
implementation "com.squareup.okhttp3:okhttp:4.7.2"
|
||||
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
||||
implementation "io.coil-kt:coil:0.11.0"
|
||||
implementation 'com.quiph.ui:recyclerviewfastscroller:0.1.3'
|
||||
implementation 'com.quiph.ui:recyclerviewfastscroller:0.2.0'
|
||||
implementation 'com.google.android.material:material:1.1.0'
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
||||
|
|
|
@ -15,6 +15,7 @@ class LoginActivity : AppCompatActivity() {
|
|||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_login)
|
||||
|
||||
setSupportActionBar(toolbar)
|
||||
supportActionBar?.title = "Login to Kobo to continue"
|
||||
|
||||
val cookieManager = CookieManager.getInstance()
|
||||
|
@ -22,7 +23,6 @@ class LoginActivity : AppCompatActivity() {
|
|||
cookieManager.setAcceptThirdPartyCookies(web, true)
|
||||
|
||||
web.settings.javaScriptEnabled = true;
|
||||
web.loadUrl("https://www.kobo.com/account/wishlist")
|
||||
web.webViewClient = object: WebViewClient() {
|
||||
override fun onPageFinished(view: WebView?, url: String?) {
|
||||
super.onPageFinished(view, url)
|
||||
|
@ -38,6 +38,10 @@ class LoginActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
cookieManager.removeAllCookies {
|
||||
web.loadUrl("https://www.kobo.com/account/wishlist")
|
||||
}
|
||||
}
|
||||
|
||||
fun getCookie(siteName: String, name: String): String? {
|
||||
|
|
|
@ -16,6 +16,7 @@ import android.view.ViewGroup
|
|||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.ActionBarDrawerToggle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.core.content.ContextCompat.startActivity
|
||||
|
@ -38,12 +39,36 @@ class MainActivity : AppCompatActivity() {
|
|||
var hasCookie = false
|
||||
val viewAdapter = BookAdapter(ArrayList())
|
||||
var totalPages = 1
|
||||
var refreshing = false
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
val app = application as WishkoboneApplication
|
||||
|
||||
setSupportActionBar(toolbar)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
supportActionBar?.title = "Your wishlist"
|
||||
val toggle =
|
||||
ActionBarDrawerToggle(this, drawerlayout, toolbar, R.string.open, R.string.close)
|
||||
drawerlayout.addDrawerListener(toggle)
|
||||
toggle.isDrawerIndicatorEnabled = true
|
||||
toggle.syncState()
|
||||
|
||||
navigation.setCheckedItem(R.id.home)
|
||||
navigation.setNavigationItemSelectedListener {
|
||||
if (it.itemId == R.id.logout) {
|
||||
app.invalidateCookie()
|
||||
hasCookie = false
|
||||
drawerlayout.closeDrawers()
|
||||
doLogin()
|
||||
return@setNavigationItemSelectedListener true
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
val viewManager = LinearLayoutManager(this)
|
||||
|
||||
status_text.text = "Loading..."
|
||||
|
@ -60,8 +85,33 @@ class MainActivity : AppCompatActivity() {
|
|||
adapter = viewAdapter
|
||||
}
|
||||
|
||||
fastscroller.setHandleStateListener(object : RecyclerViewFastScroller.HandleStateListener {
|
||||
override fun onDragged(offset: Float, position: Int) {
|
||||
Log.d("scroller", "dragged: $position")
|
||||
super.onDragged(offset, position)
|
||||
}
|
||||
|
||||
val app = application as WishkoboneApplication
|
||||
override fun onEngaged() {
|
||||
Log.d("scroller", "engaged")
|
||||
super.onEngaged()
|
||||
}
|
||||
|
||||
override fun onReleased() {
|
||||
Log.d("scroller", "released")
|
||||
super.onReleased()
|
||||
}
|
||||
})
|
||||
|
||||
refresher.setOnRefreshListener {
|
||||
if (!refreshing) {
|
||||
viewAdapter.books.clear()
|
||||
viewAdapter.filteredBooks.clear()
|
||||
viewAdapter.notifyDataSetChanged()
|
||||
refresher.isRefreshing = false
|
||||
loadBooks()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
val cookie = app.getCookie()
|
||||
if (cookie != null) {
|
||||
|
@ -71,10 +121,9 @@ class MainActivity : AppCompatActivity() {
|
|||
doLogin()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
fun doLogin(){
|
||||
fun doLogin() {
|
||||
val login = Intent(this, LoginActivity::class.java)
|
||||
startActivity(login);
|
||||
}
|
||||
|
@ -86,7 +135,7 @@ class MainActivity : AppCompatActivity() {
|
|||
val app = application as WishkoboneApplication
|
||||
val cookie = app.getCookie()
|
||||
if (cookie != null) { // we just got this via login
|
||||
|
||||
viewAdapter.books.clear()
|
||||
loadBooks()
|
||||
}
|
||||
}
|
||||
|
@ -128,7 +177,9 @@ class MainActivity : AppCompatActivity() {
|
|||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun loadBooks(page: Int = 1) {
|
||||
refreshing = true
|
||||
runOnUiThread {
|
||||
snackbar_spinner.visibility = View.VISIBLE
|
||||
status.visibility = View.VISIBLE
|
||||
status_text.text = "Loading page $page of $totalPages"
|
||||
}
|
||||
|
@ -145,7 +196,7 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
override fun onResponse(call: Call, r: Response, response: JSONObject) {
|
||||
if (!response.has("TotalNumPages")){
|
||||
if (!response.has("TotalNumPages")) {
|
||||
// must be unauthenticated
|
||||
hasCookie = false
|
||||
runOnUiThread {
|
||||
|
@ -200,10 +251,20 @@ class MainActivity : AppCompatActivity() {
|
|||
} else {
|
||||
// the end!
|
||||
runOnUiThread {
|
||||
refreshing = false
|
||||
snackbar_spinner.visibility = View.INVISIBLE
|
||||
status_text.text =
|
||||
"Load complete! ${viewAdapter.books.size} items shown."
|
||||
status.postDelayed({
|
||||
status.visibility = View.GONE
|
||||
status.animate()
|
||||
.translationY(status.height.toFloat())
|
||||
.setDuration(500)
|
||||
.withEndAction {
|
||||
status.visibility = View.GONE
|
||||
status.translationY = 0F
|
||||
}
|
||||
.start()
|
||||
|
||||
}, 3000)
|
||||
}
|
||||
}
|
||||
|
@ -211,6 +272,7 @@ class MainActivity : AppCompatActivity() {
|
|||
|
||||
override fun onFailureResponse(call: Call, r: Response, response: JSONObject) {
|
||||
hasCookie = false
|
||||
refreshing = false
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -222,7 +284,7 @@ class MainActivity : AppCompatActivity() {
|
|||
// Complex data items may need more than one view per item, and
|
||||
// you provide access to all the views for a data item in a view holder.
|
||||
// Each data item is just a string in this case that is shown in a TextView.
|
||||
private var filteredBooks: ArrayList<Book> = ArrayList()
|
||||
var filteredBooks: ArrayList<Book> = ArrayList()
|
||||
|
||||
init {
|
||||
filteredBooks.addAll(books)
|
||||
|
@ -308,6 +370,7 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
holder.itemView.setOnClickListener {
|
||||
Log.d("click", book.url)
|
||||
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(book.url))
|
||||
intent.addFlags(FLAG_ACTIVITY_NEW_TASK)
|
||||
startActivity(it.context, intent, null)
|
||||
|
@ -319,6 +382,7 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
override fun onChange(position: Int): CharSequence {
|
||||
Log.d("scroller", "$position")
|
||||
return filteredBooks[position].formattedPrice()
|
||||
}
|
||||
|
||||
|
|
|
@ -4,8 +4,25 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/coordinator"
|
||||
tools:context=".LoginActivity">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="@id/coordinator"
|
||||
android:id="@+id/appbar">
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
|
||||
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
|
||||
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<WebView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
|
|
@ -1,36 +1,75 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.drawerlayout.widget.DrawerLayout
|
||||
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:id="@+id/drawerlayout"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent">
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
|
||||
android:id="@+id/coordinator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller
|
||||
android:id="@+id/fastscroller"
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="@id/coordinator"
|
||||
android:id="@+id/appbar">
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
|
||||
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
|
||||
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:popupDrawable="@drawable/scroller_popup"
|
||||
app:handleDrawable="@drawable/scroller_thumb"
|
||||
app:layout_constraintBottom_toBottomOf="@id/coordinator"
|
||||
app:handleHeight="32dp">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/list"
|
||||
android:layout_marginTop="?attr/actionBarSize"
|
||||
android:id="@+id/refresher">
|
||||
<com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller
|
||||
android:id="@+id/fastscroller"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="none" />
|
||||
</com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller>
|
||||
app:popupDrawable="@drawable/scroller_popup"
|
||||
app:handleDrawable="@drawable/scroller_thumb"
|
||||
app:layout_constraintBottom_toBottomOf="@id/coordinator"
|
||||
app:layout_constraintTop_toBottomOf="@id/appbar"
|
||||
android:layout_marginTop="?attr/actionBarSize"
|
||||
app:supportSwipeToRefresh="true"
|
||||
app:handleHeight="32dp">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="none" />
|
||||
</com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller>
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/status"
|
||||
app:layout_constraintBottom_toBottomOf="@id/coordinator"
|
||||
android:orientation="horizontal"
|
||||
android:background="@color/colorPrimaryDark"
|
||||
android:background="@color/snackbar"
|
||||
android:paddingVertical="12dp"
|
||||
android:paddingHorizontal="15dp">
|
||||
<ProgressBar
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:indeterminate="true"
|
||||
android:layout_marginEnd="15dp"
|
||||
android:id="@+id/snackbar_spinner"
|
||||
android:indeterminateTint="@color/lineGrey"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -40,3 +79,11 @@
|
|||
/>
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<com.google.android.material.navigation.NavigationView
|
||||
android:id="@+id/navigation"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="start|left"
|
||||
app:headerLayout="@layout/drawer_header"
|
||||
app:menu="@menu/menu_nav" />
|
||||
</androidx.drawerlayout.widget.DrawerLayout>
|
24
src/main/res/layout/drawer_header.xml
Normal file
24
src/main/res/layout/drawer_header.xml
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingHorizontal="15dp"
|
||||
android:paddingVertical="30dp"
|
||||
android:background="@color/snackbar">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="19sp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textStyle="bold"
|
||||
android:text="Wishkobone"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="17sp"
|
||||
android:textColor="@color/lineGrey"
|
||||
android:text="A wishlist app for Kobo."
|
||||
/>
|
||||
</LinearLayout>
|
5
src/main/res/menu/menu_nav.xml
Normal file
5
src/main/res/menu/menu_nav.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/home" android:title="Wishlist"/>
|
||||
<item android:id="@+id/logout" android:title="Log out"/>
|
||||
</menu>
|
|
@ -2,7 +2,8 @@
|
|||
<resources>
|
||||
<color name="colorPrimary">#bf2026</color>
|
||||
<color name="colorPrimaryDark">#ab1d22</color>
|
||||
<color name="colorAccent">#4218bb</color>
|
||||
<color name="colorAccent">#ab1d22</color>
|
||||
<color name="lineGrey">#e0e0e0</color>
|
||||
<color name="secondaryGrey">#888888</color>
|
||||
<color name="snackbar">#444444</color>
|
||||
</resources>
|
|
@ -1,3 +1,5 @@
|
|||
<resources>
|
||||
<string name="app_name">Wishkobone</string>
|
||||
<string name="open">Open drawer</string>
|
||||
<string name="close">Close drawer</string>
|
||||
</resources>
|
|
@ -1,6 +1,6 @@
|
|||
<resources>
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
|
|
Loading…
Reference in a new issue