RecyclerView Items no aparece hasta que lo desploop

Estoy usando Recyclerview dentro de un Fragment siguiendo la muestra de la architecture MVP Android de Google e intenté hacer que la parte de View pasiva fuera posible siguiendo este artículo , que hace que todo el Adapter Recyclerview pasivo de los Modelos de Datos y que el presentador maneje.

Aquí está mi código del Fragmento:

 class OrderHistoryFragment : Fragment(), OrderHistoryContract.View { lateinit var mPresenter: OrderHistoryContract.Presenter lateinit var rvOrderHistory: RecyclerView lateinit var orderHistoryAdapter : OrderHistoryAdapter override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { val root = inflater!!.inflate(R.layout.order_history_fragment, container, false) rvOrderHistory = root.findViewById<RecyclerView>(R.id.rvOrderHistory) rvOrderHistory.layoutManager = LinearLayoutManager(context, LinearLayout.VERTICAL, false) orderHistoryAdapter = OrderHistoryAdapter(mPresenter, object : HistoryItemListener { override fun onReorder(orderHistory: OrderHistory) { } override fun onOpenOrder(orderHistory: OrderHistory) { val orderIntent = Intent(activity, OrderDetailActivity::class.java) orderIntent.putExtra("orderId", orderHistory.id) startActivity(orderIntent) } }) rvOrderHistory.adapter = orderHistoryAdapter return root } override fun onResume() { super.onResume() mPresenter.start() } override fun setPresenter(presenter: OrderHistoryContract.Presenter) { mPresenter = checkNotNull<OrderHistoryContract.Presenter>(presenter) } override fun showLoadingIndicator(load: Boolean?) { } override fun updateOrdersAdapter() { orderHistoryAdapter.notifyDataSetChanged() } override fun showSnackBar(Message: String) { val parentLayout = activity.findViewById<View>(android.R.id.content) val snackBar = Snackbar .make(parentLayout, Message, Snackbar.LENGTH_INDEFINITE) snackBar.setAction("Dismiss") { snackBar.dismiss() } snackBar.setActionTextColor(Color.RED) snackBar.show() } interface HistoryItemListener { fun onReorder(orderHistory: OrderHistory) fun onOpenOrder(orderHistory: OrderHistory) } companion object { fun newInstance(): OrderHistoryFragment { return OrderHistoryFragment() } } fun OrderHistoryFragment() { } } 

Y este es mi código RecyclerView Adapters

 class OrderHistoryAdapter(internal var orderHistoryPresenter: OrderHistoryContract.Presenter, private val listener: OrderHistoryFragment.HistoryItemListener) : RecyclerView.Adapter<OrderHistoryAdapter.ViewHolder>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(parent.context) .inflate(R.layout.order_history_item, parent, false) return ViewHolder(view) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { orderHistoryPresenter.onBindOrdersRow(position, holder) holder.bReOrder!!.setOnClickListener { v -> listener.onReorder(orderHistoryPresenter.getOrderHistoryItem(position)) } holder.cvOrderItem!!.setOnClickListener { v -> listener.onOpenOrder(orderHistoryPresenter.getOrderHistoryItem(position)) } } override fun getItemId(position: Int): Long { return position.toLong() } override fun getItemCount(): Int { return orderHistoryPresenter.getOrdersCount() } class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), OrderHistoryContract.orderRowView { internal var ivOrderVendor: ImageView? = null internal var tvOrderId: TextView? = null internal var tvOrderItems: TextView? = null internal var tvOrderDate: TextView? = null internal var tvOrderPrice: TextView? = null internal var bReOrder: Button? = null internal var cvOrderItem: CardView? = null init { ivOrderVendor = itemView.findViewById<ImageView>(R.id.ivOrderVendor) tvOrderId = itemView.findViewById<TextView>(R.id.tvOrderId) tvOrderItems = itemView.findViewById<TextView>(R.id.tvOrderItems) tvOrderDate = itemView.findViewById<TextView>(R.id.tvOrderDate) tvOrderPrice = itemView.findViewById<TextView>(R.id.tvOrderPrice) bReOrder = itemView.findViewById<Button>(R.id.bReOrder) cvOrderItem = itemView.findViewById<CardView>(R.id.cvOrderItem) } override fun setOrderImage(url: String) { Glide.with(itemView.context).load(url).into(ivOrderVendor!!) } override fun setOrderDate(orderDate: String) { tvOrderDate!!.text = orderDate } override fun setOrderId(orderId: String) { tvOrderId!!.text = orderId } override fun setOrderItems(orderItems: ArrayList<String>) { val stringBuilder = StringBuilder() for (item in orderItems) { stringBuilder.append(item) } tvOrderItems!!.text = stringBuilder.toString() } override fun setOrderPrice(orderPrice: String) { tvOrderPrice!!.text = R.string.price.toString() + " " + orderPrice + " " + R.string.egp } } } 

Y aquí está el código del presentador que maneja los datos del Adapter y es binding para ViewHolder

 class OrderHistoryPresenter internal constructor(mDataRepository: DataRepository, mOrdeHistoryView: OrderHistoryContract.View) : OrderHistoryContract.Presenter { private val mDataRepository: DataRepository //refrence of the View to trigger the functions after proccessing the task private val mOrdeHistoryView: OrderHistoryContract.View private var orderHistoryItems = ArrayList<OrderHistory>() init { this.mDataRepository = checkNotNull(mDataRepository, "tasksRepository cannot be null") this.mOrdeHistoryView = checkNotNull<OrderHistoryContract.View>(mOrdeHistoryView, "tasksView cannot be null!") mOrdeHistoryView.setPresenter(this) } override fun start() { mOrdeHistoryView.showLoadingIndicator(true) mDataRepository.getCurrentUser(object : LocalDataSource.userRequestCallback { override fun onUserRequestSuccess(botitUser: BotitUser) { val urlParams = HashMap<String, String>() urlParams.put(Endpoints.USER_ID_KEY, botitUser.userId!!) val url = Endpoints.getUrl(Endpoints.urls.ORDER_HISTORY, urlParams) mDataRepository.buildEndPointRequest(url, " ", Endpoints.requestsType.GET, object : EndpointDataSource.RequestCallback { override fun onRequestSuccess(Body: String) { try { mOrdeHistoryView.showLoadingIndicator(false) orderHistoryItems = JSONParser.parseData(JSONParser.parsers.ORDER_HISTORY, JSONObject(Body)) as ArrayList<OrderHistory> mOrdeHistoryView.updateOrdersAdapter() } catch (e: JSONException) { e.printStackTrace() } } override fun onRequestError(Body: String) { mOrdeHistoryView.showLoadingIndicator(false) mOrdeHistoryView.showSnackBar("Cannot load data") } }) } override fun onUserRequestError(Body: String) { } }) } override fun refreshData() { } override fun getOrdersCount(): Int { return orderHistoryItems.size } override fun onBindOrdersRow(position: Int, orderViewHolder: OrderHistoryContract.orderRowView) { if (orderHistoryItems.isNotEmpty()) { val orderHistory = orderHistoryItems[position] // orderViewHolder.setOrderDate(orderHistory.orderDate!!) orderViewHolder.setOrderId(orderHistory.orderId!!) orderViewHolder.setOrderImage(orderHistory.orderImage!!) orderViewHolder.setOrderItems(orderHistory.orderItems) orderViewHolder.setOrderPrice(orderHistory.orderPrice!!) } } override fun getOrderHistoryItem(position: Int): OrderHistory { return orderHistoryItems[position] } override fun actionReOrder(ordreId: String) { } } 

Aquí está el Fragment XML

 <android.support.v7.widget.RecyclerView android:layout_width="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/rvOrderHistory" android:layout_height="match_parent" xmlns:android="http://schemas.android.com/apk/res/android"> </android.support.v7.widget.RecyclerView> 

y aquí está el artículo de RecyclerView XML order_history_item.xml

 <?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView 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="wrap_content" android:id="@+id/cvOrderItem" android:layout_margin="4dp" android:orientation="vertical"> <android.support.constraint.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:orientation="vertical" android:padding="8dp"> <ImageView android:id="@+id/ivOrderVendor" android:layout_width="60dp" android:layout_height="60dp" android:layout_marginEnd="8dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@drawable/mac" /> <TextView android:id="@+id/tvOrderId" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="8dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:text="Order #2123" android:textAppearance="@style/TextAppearance.AppCompat.Body2" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintLeft_toRightOf="@+id/ivOrderVendor" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/tvOrderItems" android:layout_width="242dp" android:layout_height="35dp" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" android:text="MacDonald's: Big Mac Beef, Big Tasty Beef. El Ezaby: Signal 2, Pantene Shampoo" android:textAppearance="@style/TextAppearance.AppCompat.Small" android:layout_marginRight="8dp" app:layout_constraintRight_toRightOf="parent" android:layout_marginTop="8dp" app:layout_constraintTop_toBottomOf="@+id/tvOrderId" app:layout_constraintLeft_toRightOf="@+id/ivOrderVendor" android:layout_marginLeft="8dp" app:layout_constraintHorizontal_bias="0.0" /> <TextView android:id="@+id/tvOrderDate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:layout_marginEnd="16dp" android:layout_marginRight="16dp" android:layout_marginTop="8dp" android:text="03:22 PM 23/2/2017" app:layout_constraintBottom_toTopOf="@+id/tvOrderItems" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.0" android:layout_marginLeft="8dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintHorizontal_bias="1.0" /> <TextView android:id="@+id/tvOrderPrice" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="8dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:layout_marginStart="8dp" android:layout_marginTop="16dp" android:text="Price: 225.50 LE" android:textAppearance="@style/TextAppearance.AppCompat.Body2" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@+id/tvOrderItems" /> <Button android:id="@+id/bReOrder" android:layout_width="wrap_content" android:layout_height="35dp" android:layout_margin="4dp" android:background="@drawable/chip_accent" android:foreground="?attr/selectableItemBackground" android:orientation="vertical" android:padding="8dp" android:text="Order Again" android:textAllCaps="false" android:textColor="@color/colorAccent" android:textSize="15sp" app:layout_constraintHorizontal_bias="0.937" app:layout_constraintLeft_toRightOf="@+id/tvOrderPrice" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@+id/tvOrderItems" tools:layout_editor_absoluteY="74dp" /> </android.support.constraint.ConstraintLayout> </android.support.v7.widget.CardView> 

El problema es que cuando comienzo la Activity muestra el Fragment , el RecyclerView no muestra el Artículo. Solo aparece si recorrí el RecyclerView vacío o si dejo la aplicación en primer plano y vuelvo a ella.

En la initialization, los datos del Adapter están vacíos, pero onResume() realizo una request que actualiza los datos en el presentador, luego notifyDataChange() en el Adapter pero no se actualiza nada.

Cuando onBindViewHolder() descubrí que onBindViewHolder() no se llama después de notifyDataChange() en el Adaptador, por lo que no sé por qué notifyDataChange() no notifica al Adapter que los datos se han cambiado.

¿Alguien tiene una idea o alguna solución que pueda solucionar este problema?