1

我使用Recyclerview一个FragmentGoogle's sample of MVP Android的架构里面,我试图让View部分被动地跟踪this article,这使得整个RecyclerviewAdapter被动的数据模型演示者处理它。RecyclerView项目没有出现,直到我把它的滚动

这里是我的片段代码:

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() { 

    } 

} 

这是我RecyclerView适配器代码

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 

     } 
    } 


} 

,这里是演示的代码处理Adapter数据它绑定到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) { 


    } 


} 

这里是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> 

这里是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> 

的问题是,当我开始Activity显示FragmentRecyclerView不显示该项目。只有当我滚动空的RecyclerView或将应用程序放在前台并再次返回时才会出现。

在初始化的Adapter的数据是空的,但我onResume()使这在演示更新数据的请求,然后我notifyDataChange()Adapter但没有更新。

当我调试,我发现onBindViewHolder()notifyDataChange()后呼吁适配器,所以我不知道为什么notifyDataChange()没有通知Adapter数据被改变。

任何人有一个想法或任何解决方案,可以解决这个问题?

+0

您是否找到解决方案? – CiDsTaR

回答

0

我注意到你的项目xml你的constraintLayout高度是match_parent吧? 我建议您使用它作为wrap_content

+0

我试过了,它不会改变任何东西 –

+0

尝试在项目根元素中使用固定大小。像100dp或200dp,看看问题是否存在 –

相关问题