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 'org.greenrobot:eventbus:3.1.1'
}

View File

@ -11,6 +11,7 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:theme="@style/AppTheme">
<activity
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 kotlinx.android.synthetic.main.activity_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.adapter.HomeProductAdapter
import me.gilo.wc.adapter.ImagePagerAdapter
import me.gilo.wc.adapter.ProductReviewAdapter
import me.gilo.wc.common.BaseActivity
import me.gilo.wc.common.Status
import me.gilo.wc.events.ProductEvent
import me.gilo.wc.ui.state.ProgressDialogFragment
import me.gilo.wc.viewmodels.ProductViewModel
import me.gilo.woodroid.models.Product
import me.gilo.woodroid.models.ProductReview
import me.gilo.woodroid.models.filters.ProductFilter
import java.util.ArrayList
import org.greenrobot.eventbus.EventBus
import java.util.*
class ProductActivity : BaseActivity() {
@ -40,8 +42,6 @@ class ProductActivity : BaseActivity() {
if (productId != 0){
product(productId)
reviews(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) {
viewModel.addToCart(baseContext, productId).observe(this, android.arch.lifecycle.Observer { response ->
when (response!!.status()) {
@ -131,7 +85,9 @@ class ProductActivity : BaseActivity() {
Status.SUCCESS -> {
val product = response.data()
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) {
tvTitle.text = product.name
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>
<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"/>
<fragment
android:name="me.gilo.wc.ui.product.section.RelatedProductsFragment"
android:id="@+id/fRelatedProducts"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v7.widget.RecyclerView
<fragment
android:name="me.gilo.wc.ui.product.section.ProductReviewsFragment"
android:id="@+id/fProductReviews"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/rvShop"
></android.support.v7.widget.RecyclerView>
android:layout_height="wrap_content" />
<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>
</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 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;
public AddCookiesInterceptor(Context context) {

View File

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