Composable UI approach with fragments on the product page

This commit is contained in:
Gilbert Kimutai 2019-03-24 07:50:59 +03:00
parent 3134e59f4c
commit 53e6f95ab7
12 changed files with 346 additions and 132 deletions

View File

@ -90,5 +90,7 @@ dependencies {
implementation 'net.danlew:android.joda:2.9.9.4' implementation 'net.danlew:android.joda:2.9.9.4'
implementation 'org.greenrobot:eventbus:3.1.1'
} }

View File

@ -11,6 +11,7 @@
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">
<activity <activity
android:name=".ui.home.HomeActivity" android:name=".ui.home.HomeActivity"

View File

@ -0,0 +1,20 @@
package me.gilo.wc.events;
import me.gilo.woodroid.models.Product;
public class ProductEvent {
Product product;
public ProductEvent(Product product) {
this.product = product;
}
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
}

View File

@ -7,18 +7,20 @@ import android.util.Log
import android.view.View import android.view.View
import kotlinx.android.synthetic.main.activity_product.* import kotlinx.android.synthetic.main.activity_product.*
import kotlinx.android.synthetic.main.content_product.* import kotlinx.android.synthetic.main.content_product.*
import kotlinx.android.synthetic.main.section_product_reviews.*
import me.gilo.wc.R import me.gilo.wc.R
import me.gilo.wc.adapter.HomeProductAdapter import me.gilo.wc.adapter.HomeProductAdapter
import me.gilo.wc.adapter.ImagePagerAdapter import me.gilo.wc.adapter.ImagePagerAdapter
import me.gilo.wc.adapter.ProductReviewAdapter import me.gilo.wc.adapter.ProductReviewAdapter
import me.gilo.wc.common.BaseActivity import me.gilo.wc.common.BaseActivity
import me.gilo.wc.common.Status import me.gilo.wc.common.Status
import me.gilo.wc.events.ProductEvent
import me.gilo.wc.ui.state.ProgressDialogFragment import me.gilo.wc.ui.state.ProgressDialogFragment
import me.gilo.wc.viewmodels.ProductViewModel import me.gilo.wc.viewmodels.ProductViewModel
import me.gilo.woodroid.models.Product import me.gilo.woodroid.models.Product
import me.gilo.woodroid.models.ProductReview import me.gilo.woodroid.models.ProductReview
import me.gilo.woodroid.models.filters.ProductFilter import org.greenrobot.eventbus.EventBus
import java.util.ArrayList import java.util.*
class ProductActivity : BaseActivity() { class ProductActivity : BaseActivity() {
@ -40,8 +42,6 @@ class ProductActivity : BaseActivity() {
if (productId != 0){ if (productId != 0){
product(productId) product(productId)
reviews(productId)
} }
fab.setOnClickListener{addToCart(productId)} fab.setOnClickListener{addToCart(productId)}
@ -49,52 +49,6 @@ class ProductActivity : BaseActivity() {
} }
lateinit var adapter: HomeProductAdapter
private lateinit var products: ArrayList<Product>
//TODO(Use the include product filter to get related products from API)
private fun similarProducts(product: Product) {
val layoutManager = LinearLayoutManager(baseContext, LinearLayoutManager.HORIZONTAL, false)
rvShop.layoutManager = layoutManager
rvShop.isNestedScrollingEnabled = false
products = ArrayList()
adapter = HomeProductAdapter(products)
rvShop.adapter = adapter
val filter = ProductFilter()
filter.include = product.related_ids.toIntArray()
viewModel.products(filter).observe(this, android.arch.lifecycle.Observer { response ->
when (response!!.status()) {
Status.LOADING -> {
}
Status.SUCCESS -> {
products.clear()
val productsResponse = response.data()
for (product in productsResponse) {
products.add(product)
}
adapter.notifyDataSetChanged()
}
Status.ERROR -> {
}
Status.EMPTY -> {
}
}
})
}
private fun addToCart(productId: Int) { private fun addToCart(productId: Int) {
viewModel.addToCart(baseContext, productId).observe(this, android.arch.lifecycle.Observer { response -> viewModel.addToCart(baseContext, productId).observe(this, android.arch.lifecycle.Observer { response ->
when (response!!.status()) { when (response!!.status()) {
@ -131,7 +85,9 @@ class ProductActivity : BaseActivity() {
Status.SUCCESS -> { Status.SUCCESS -> {
val product = response.data() val product = response.data()
setUpPage(product) setUpPage(product)
similarProducts(product) //similarProducts(product)
EventBus.getDefault().post(ProductEvent(product))
} }
@ -149,49 +105,6 @@ class ProductActivity : BaseActivity() {
} }
private fun reviews(productId : Int) {
val layoutManager = LinearLayoutManager(baseContext, LinearLayoutManager.VERTICAL, false)
rvReviews.layoutManager = layoutManager
rvReviews.isNestedScrollingEnabled = false
var reviews = ArrayList<ProductReview>()
var productReviewAdapter = ProductReviewAdapter(reviews)
rvReviews.adapter = productReviewAdapter
viewModel.reviews(productId).observe(this, android.arch.lifecycle.Observer { response ->
when (response!!.status()) {
Status.LOADING -> {
}
Status.SUCCESS -> {
reviews.clear()
val reviewsResponse = response.data()
for (review in reviewsResponse) {
reviews.add(review)
}
productReviewAdapter.notifyDataSetChanged()
}
Status.ERROR -> {
Log.d("Error", response.error().message)
}
Status.EMPTY -> {
}
}
})
}
private fun setUpPage(product: Product) { private fun setUpPage(product: Product) {
tvTitle.text = product.name tvTitle.text = product.name
tvDescription.text = Html.fromHtml(product.description) tvDescription.text = Html.fromHtml(product.description)

View File

@ -0,0 +1,107 @@
package me.gilo.wc.ui.product.section
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v7.widget.LinearLayoutManager
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.section_product_reviews.*
import me.gilo.wc.R
import me.gilo.wc.adapter.ProductReviewAdapter
import me.gilo.wc.common.BaseActivity
import me.gilo.wc.common.Status
import me.gilo.wc.ui.product.ProductActivity
import me.gilo.wc.viewmodels.ProductViewModel
import me.gilo.woodroid.models.ProductReview
import org.greenrobot.eventbus.EventBus
import java.util.*
class ProductReviewsFragment : Fragment() {
lateinit var viewModel: ProductViewModel
val TAG = "ProductReviewsFragment"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return inflater.inflate(R.layout.section_product_reviews, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = (activity as BaseActivity).getViewModel(ProductViewModel::class.java)
var productId = (activity as ProductActivity).intent.getIntExtra("productId", 0)
reviews(productId)
}
private fun reviews(productId : Int) {
val layoutManager = LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false)
rvReviews.layoutManager = layoutManager
rvReviews.isNestedScrollingEnabled = false
var reviews = ArrayList<ProductReview>()
var productReviewAdapter = ProductReviewAdapter(reviews)
rvReviews.adapter = productReviewAdapter
viewModel.reviews(productId).observe(this, android.arch.lifecycle.Observer { response ->
when (response!!.status()) {
Status.LOADING -> {
}
Status.SUCCESS -> {
reviews.clear()
val reviewsResponse = response.data()
for (review in reviewsResponse) {
reviews.add(review)
}
productReviewAdapter.notifyDataSetChanged()
}
Status.ERROR -> {
Log.d("Error", response.error().message)
}
Status.EMPTY -> {
}
}
})
}
companion object {
@JvmStatic
fun newInstance() =
ProductReviewsFragment().apply {
arguments = Bundle().apply {
}
}
}
}

View File

@ -0,0 +1,128 @@
package me.gilo.wc.ui.product.section
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v7.widget.LinearLayoutManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.section_related_products.*
import me.gilo.wc.R
import me.gilo.wc.adapter.HomeProductAdapter
import me.gilo.wc.common.BaseActivity
import me.gilo.wc.common.Status
import me.gilo.wc.events.ProductEvent
import me.gilo.wc.viewmodels.ProductViewModel
import me.gilo.woodroid.models.Product
import me.gilo.woodroid.models.filters.ProductFilter
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.util.*
class RelatedProductsFragment : Fragment() {
lateinit var viewModel: ProductViewModel
val TAG = "RelatedProductFragment"
lateinit var adapter: HomeProductAdapter
private lateinit var products: ArrayList<Product>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return inflater.inflate(R.layout.section_related_products, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = (activity as BaseActivity).getViewModel(ProductViewModel::class.java)
//similarProducts()
}
private fun similarProducts(product: Product) {
val layoutManager = LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false)
rvShop.layoutManager = layoutManager
rvShop.isNestedScrollingEnabled = false
products = ArrayList()
adapter = HomeProductAdapter(products)
rvShop.adapter = adapter
val filter = ProductFilter()
filter.include = product.related_ids.toIntArray()
viewModel.products(filter).observe(this, android.arch.lifecycle.Observer { response ->
when (response!!.status()) {
Status.LOADING -> {
}
Status.SUCCESS -> {
products.clear()
val productsResponse = response.data()
for (product in productsResponse) {
products.add(product)
}
adapter.notifyDataSetChanged()
}
Status.ERROR -> {
}
Status.EMPTY -> {
}
}
})
}
override fun onStart() {
super.onStart()
EventBus.getDefault().register(this)
}
override fun onStop() {
super.onStop()
EventBus.getDefault().unregister(this)
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: ProductEvent) {
similarProducts(event.product)
}
companion object {
@JvmStatic
fun newInstance() =
RelatedProductsFragment().apply {
arguments = Bundle().apply {
}
}
}
}

View File

@ -107,44 +107,20 @@
</LinearLayout> </LinearLayout>
<TextView <fragment
fontPath="@string/font_medium" android:name="me.gilo.wc.ui.product.section.RelatedProductsFragment"
android:layout_width="wrap_content" android:id="@+id/fRelatedProducts"
android:layout_height="wrap_content"
android:gravity="left"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:layout_marginRight="16dp"
android:text="More Like this"
android:textColor="@color/text_black_2"
android:textSize="20sp"/>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content" />
android:id="@+id/rvShop"
></android.support.v7.widget.RecyclerView>
<fragment
<TextView android:name="me.gilo.wc.ui.product.section.ProductReviewsFragment"
fontPath="@string/font_medium" android:id="@+id/fProductReviews"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:layout_marginRight="16dp"
android:text="Reviews"
android:textColor="@color/text_black_2"
android:textSize="20sp"/>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content" />
android:id="@+id/rvReviews"
android:background="@drawable/rect_white"
android:layout_margin="16dp"
></android.support.v7.widget.RecyclerView>
</LinearLayout> </LinearLayout>
</android.support.v4.widget.NestedScrollView> </android.support.v4.widget.NestedScrollView>

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:ignore="MissingPrefix"
>
<TextView
fontPath="@string/font_medium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:layout_marginRight="16dp"
android:text="Reviews"
android:textColor="@color/text_black_2"
android:textSize="20sp"/>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/rvReviews"
android:background="@drawable/rect_white"
android:layout_margin="16dp"
></android.support.v7.widget.RecyclerView>
</LinearLayout>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:ignore="MissingPrefix"
>
<TextView
fontPath="@string/font_medium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:layout_marginRight="16dp"
android:text="More Like this"
android:textColor="@color/text_black_2"
android:textSize="20sp"/>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/rvShop"
></android.support.v7.widget.RecyclerView>
</LinearLayout>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">157.230.131.179</domain>
</domain-config>
</network-security-config>

View File

@ -12,8 +12,6 @@ import java.util.HashSet;
public class AddCookiesInterceptor implements Interceptor { public class AddCookiesInterceptor implements Interceptor {
public static final String PREF_COOKIES = "PREF_COOKIES"; public static final String PREF_COOKIES = "PREF_COOKIES";
// We're storing our stuff in a database made just for cookies called PREF_COOKIES.
// I reccomend you do this, and don't change this default value.
private Context context; private Context context;
public AddCookiesInterceptor(Context context) { public AddCookiesInterceptor(Context context) {

View File

@ -2,7 +2,9 @@ package me.gilo.woodroid.repo;
import android.content.Context; import android.content.Context;
import me.gilo.woodroid.data.api.CartAPI; import me.gilo.woodroid.data.api.CartAPI;
import me.gilo.woodroid.data.cookie.AddCookiesInterceptor;
import me.gilo.woodroid.data.cookie.DemoCookieInterceptor; import me.gilo.woodroid.data.cookie.DemoCookieInterceptor;
import me.gilo.woodroid.data.cookie.ReceivedCookiesInterceptor;
import me.gilo.woodroid.models.LineItem; import me.gilo.woodroid.models.LineItem;
import me.gilo.woodroid.models.filters.CartFilter; import me.gilo.woodroid.models.filters.CartFilter;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
@ -49,9 +51,8 @@ public class CartRepository{
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder() OkHttpClient client = new OkHttpClient.Builder()
// .addInterceptor(new AddCookiesInterceptor(context)) .addInterceptor(new AddCookiesInterceptor(context))
// .addInterceptor(new ReceivedCookiesInterceptor(context)) .addInterceptor(new ReceivedCookiesInterceptor(context))
.addInterceptor(new DemoCookieInterceptor())
.addInterceptor(loggingInterceptor) .addInterceptor(loggingInterceptor)
.readTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS)