14

這是我第一次嘗試與RecyclerView進行數據綁定,但不是我第一次使用RecyclerView本身。RecyclerView和數據綁定不起作用

出於某種原因,沒有任何適配器方法被調用 - 甚至沒有getItemCount()。 這可能是與我的RecyclerView並沒有什麼愚蠢的問題做的數據都具有約束力,但我看不出什麼毛病。

 View rootview = inflater.inflate(R.layout.fragment_profile_first, container, false); 
    // Initialize recycler view 

    RecyclerView badgesRV = (RecyclerView) rootview.findViewById(R.id.badgesRV); 
    LinearLayoutManager llm = new LinearLayoutManager(getActivity()); 
    llm.setOrientation(LinearLayoutManager.HORIZONTAL); 
    badgesRV.setLayoutManager(llm); 

    BadgeAdapter badgeAdapter = new BadgeAdapter(profileObject.badgesEntity.badges); 
    badgesRV.setAdapter(badgeAdapter); 

適配器:

public class BadgeAdapter extends RecyclerView.Adapter<BadgeAdapter.BadgeBindingHolder>{ 

    private static final int MAX_BADGES_TO_DISPLAY = 5; 
    private BadgeObject[] badges; 

    public BadgeAdapter(BadgeObject[] badges){ 
     this.badges = badges; 
    } 

    @Override 
    public BadgeBindingHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View v = LayoutInflater.from(parent.getContext()) 
       .inflate(R.layout.profile_badge_row, parent, false); 
     BadgeBindingHolder holder = new BadgeBindingHolder(v); 
     return holder; 
    } 

    @Override 
    public void onBindViewHolder(BadgeBindingHolder holder, int position) { 
     final BadgeObject badgeObject = badges[position]; 
     holder.getBinding().setVariable(BR.badge, badgeObject); 
     holder.getBinding().executePendingBindings(); 

    } 

    @Override 
    public int getItemCount() { 
     Log.d(TAG, "item count = " + Math.min(MAX_BADGES_TO_DISPLAY, badges.length)); 
     return Math.min(MAX_BADGES_TO_DISPLAY, badges.length); 
    } 

    public class BadgeBindingHolder extends RecyclerView.ViewHolder{ 
     private ViewDataBinding binding; 

     public BadgeBindingHolder(View rowView) { 
      super(rowView); 
      binding = DataBindingUtil.bind(rowView); 
     } 
     public ViewDataBinding getBinding() { 
      return binding; 
     } 
    } 
} 

profile_badge_row.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto"> 

<data> 
    <variable name="badge" type="parseJsonEntities.requestObjects.BadgeObject"/> 
</data> 

<LinearLayout 
    android:orientation="vertical" android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <ImageView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:src="@{badge.badgeImage}"/> 

</LinearLayout> 

我已經確認並肯定是有數據存在。 我錯過了什麼?

=====================

更新:

從我可以告訴RecyclerView根本沒有數據在裏面工作綁定佈局。 我創建了一個單獨的佈局,只有我的房車,它的工作完美。 只要我將它與主佈局一起使用,它就停止工作。

不知道這是一個錯誤還是一個功能。

所以,我認爲,也許如果我把它做成一個自定義的視圖,也許它會工作,它確實。 我的問題是我不知道如何將值傳遞到我的自定義視圖。

我看了here,但無法弄清楚他的意思。 這是我在自定義視圖中的代碼。

LayoutInflater inflater = (LayoutInflater) 
      context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    View view = inflater.inflate(R.layout.profile_badges_layout, this, true); 
    ProfileBadgesLayoutBinding binding = ProfileBadgesLayoutBinding.inflate(inflater); 

    RecyclerView badgesRV = (RecyclerView) view.findViewById(R.id.badgesRV); 

    LinearLayoutManager llm = new LinearLayoutManager(context); 
    llm.setOrientation(LinearLayoutManager.HORIZONTAL); 
    badgesRV.setLayoutManager(llm); 

    BadgeAdapter badgeAdapter = new BadgeAdapter(null); 
    badgesRV.setAdapter(badgeAdapter); 

這給出了一條消息,指出找不到ProfileBadgesLayoutBinding。

+0

哪裏是你的片段XML? –

+0

'RecyclerView'完美適用於'DataBinding',因爲許多其他人使用它沒有問題。您可以將您的佈局發佈到「RecyclerView」所在的位置嗎?也許一些奇怪的行爲與其他滾動視圖。 – yennsarah

+1

另外,什麼是'badge.badgeImage'?一個'資源ID',一個'Drawable' ..? – yennsarah

回答

14

在你onCreateViewHolder

@Override 
public BadgeBindingHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    ProfileBadgeRowBinding binding = DataBindingUtil.inflate(inflater, R.layout.profile_badge_row, parent, false); 
    BadgeBindingHolder holder = new BadgeBindingHolder(binding.getRoot(), binding); 
    return holder; 
} 

,並添加您的項目查看

public class BadgeBindingHolder extends RecyclerView.ViewHolder{ 
    private ProfileBadgeRowBinding binding; 

    public BadgeBindingHolder(View rowView, ProfileBadgeRowBinding binding) { 
     super(rowView); 
     this.binding = binding; 
    } 

    ... 

} 

而且在bindToViewHolder設置變量

@Override 
public void bindToViewHolder(RecyclerView.ViewHolder viewHolder) { 
    ProfileBadgeRowBinding binding = ((BadgeBindingHolder) viewHolder).binding; 
    binding.setVariable(BR.badge, badge); 
    binding.executePendingBindings(); // This line is important, it will force to load the variable in a custom view 
} 

綁定如果您想訪問視圖,請在您的xml的視圖中添加一個ID。

<layout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto"> 

    <data> 
     <variable name="badge" type="parseJsonEntities.requestObjects.BadgeObject"/> 
    </data> 

    <LinearLayout 
     android:orientation="vertical" android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     <ImageView 
      android:id="@+id/image" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" /> 

    </LinearLayout> 
</layout> 

然後你就可以訪問該ID在你的bindToViewHolder

@Override 
public void bindToViewHolder(RecyclerView.ViewHolder viewHolder) { 
    ProfileBadgeRowBinding binding = ((BadgeBindingHolder) viewHolder).binding; 
    binding.setVariable(BR.badge, badge); 
    binding.executePendingBindings(); 

    binding.image.setImage(...); 
} 

更多關於自定義視圖https://developer.android.com/topic/libraries/data-binding/index.html#dynamic_variables

+2

謝謝!我的問題是,我沒有使用binding.executePendingBindings(); 它看起來並不那麼明顯。 非常感謝你! – Jack

+0

救生員。 +1這對我來說工作得很好。 – TharakaNirmana