如何在排序数据时更新RecyclerView?

时间:2019-02-06 20:33:53

标签: android android-recyclerview recycler-adapter

我的数据库(Firestore)存储了Chart个由User个创建的User个。

打开应用程序后,Charts会显示为自己的MyChartsFragment,并按图表名称排序(显示在名为Charts的片段中)。他们可以单击按钮来更改排序字段。这应该检索相同的MyChartsFragment列表,但按所选字段排序。

我可以将新的排序字段名称传递到Charts中,但是此时MyChartsFragment的列表为空。我认为我需要以某种方式重绘它。

public class FragmentMyCharts extends FragmentChartsList { public FragmentMyCharts() {} public Query getQuery(FirebaseFirestore databaseReference, String orderBy) { // Specify the query which is used to retrieve this user's charts return databaseReference.collection("charts") .whereEqualTo("uid", getUid()) .orderBy(orderBy); } } 如下(为清楚起见,我删除了大多数try-catch块,错误检查等):

FragmentChartsList

这扩展了public abstract class FragmentChartsList extends Fragment { private FirebaseFirestore mDatabaseRef; private FirestoreRecyclerAdapter<Chart, ChartViewHolder> mAdapter; private Query mChartsQuery; private RecyclerView mRecycler; private String mOrder = "name"; FragmentManager mFragmentManager; ToolbarFragmentListCharts mFragmentTLC; public FragmentChartsList() {} @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); // Inflate layout, and find Recycler View to hold the list View rootView = inflater.inflate( R.layout.fragment_charts_list, container, false); mRecycler = rootView.findViewById(R.id.charts_list); mRecycler.setHasFixedSize(true); // Set up Layout Manager, and set Recycler View to use it LinearLayoutManager mManager = new LinearLayoutManager(getActivity()); mManager.setReverseLayout(true); mManager.setStackFromEnd(true); mRecycler.setLayoutManager(mManager); // Connect to the database, and get the appropriate query mDatabaseRef = FirebaseFirestore.getInstance(); mChartsQuery = getQuery(mDatabaseRef, mOrder); // Set up Recycler Adapter FirestoreRecyclerOptions<Chart> recyclerOptions = new FirestoreRecyclerOptions.Builder<Chart>() .setQuery(mChartsQuery, Chart.class) .build(); mAdapter = new ChartListAdapter(recyclerOptions, this.getActivity()); // Use Recycler Adapter in RecyclerView mRecycler.setAdapter(mAdapter); return rootView; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Add listener to charts collection, and deal with any changes by re-showing the list mChartsQuery.addSnapshotListener(new EventListener<QuerySnapshot>() { @Override public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots, @Nullable FirebaseFirestoreException e) { if (queryDocumentSnapshots != null && queryDocumentSnapshots.isEmpty()) { ((MainActivity) Objects.requireNonNull(getActivity())).setPage(1); } } }); } @Override public void onStart() { super.onStart(); mAdapter.startListening(); } public void setOrderField(String order) { mOrder = order; mChartsQuery = getQuery(mDatabaseRef, mOrder); // Set up Recycler Adapter FirestoreRecyclerOptions<Chart> recyclerOptions = new FirestoreRecyclerOptions.Builder<Chart>() .setQuery(mChartsQuery, Chart.class) .build(); mAdapter = new ChartListAdapter(recyclerOptions, this.getActivity()); // Use Recycler Adapter in RecyclerView mRecycler.setAdapter(mAdapter); } public abstract Query getQuery(FirebaseFirestore databaseReference, String orderBy); } ,其中包含:

public void setOrder(String order) {

        FragmentChartsList myCharts = (FragmentChartsList) mPagerAdapter.getItem(0);
        myCharts.setOrderField(order);

    }

因此,当工具栏通知主活动排序字段已更改时,它将检索MyChartsFragment(作为FragmentChartsList)并调用setOrderField函数:

ChartListAdapter

这似乎可以正确更新mOrder的值,但是它不会重新显示RecyclerView,所以我只得到一个空白。

我在做什么错了?

编辑以添加详细信息:

我的public class ChartListAdapter extends FirestoreRecyclerAdapter<Chart, ChartViewHolder> { private Activity mActivity; private FirestoreRecyclerOptions<Chart> recyclerOptions; public ChartListAdapter(FirestoreRecyclerOptions<Chart> recyclerOptions, Activity activity) { super(recyclerOptions); mActivity = activity; } @Override protected void onBindViewHolder(@NonNull ChartViewHolder holder, int position, @NonNull Chart model) { final String chartKey = this.getSnapshots().getSnapshot(position).getId(); model.setKey(chartKey); // Set click listener for the chart holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(mActivity, ActivityViewChart.class); intent.putExtra("ChartKey", chartKey); mActivity.startActivity(intent); } }); // Implement long-click menu mActivity.registerForContextMenu(holder.itemView); // Bind Chart to ViewHolder holder.bindToChart(model); } @NonNull @Override public ChartViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_chart, parent, false); return new ChartViewHolder(view); } public void setRecyclerOptions(FirestoreRecyclerOptions<Chart> recyclerOptions) { this.recyclerOptions = recyclerOptions; } } 类是:

 library(readr)
 library(dplyr)
 titanic_train <- read_csv("C:/Users/johnt/Desktop/Statistical Data Mining/HW 1/train.csv")

 titanic_train <- titanic_train %>% 
   select(Survived, Pclass, Sex, Age, SibSp, Parch, Fare, Embarked) %>% 
   mutate(Fare = log(Fare))


 ###### Model Matrix

 mm <- titanic_train %>% 
   select(Pclass, Age, SibSp, Parch, Fare, Survived) 

 titan <- model.matrix(-Survived ~., mm)

 #Clean it up
 titan <- titan[,-1] #remove intercept column
 titan <- scale(titan)
 titan[is.na(titan)] <- 0

 #PCA
 titan2 <-prcomp(titan[,-5], center = TRUE, scale. = TRUE)
 titan2


 plot(titan2$x[,1:2],col=mm$Survived)

4 个答案:

答案 0 :(得分:1)

而不是重新创建recyclerView适配器,尝试更新适配器中的选项。

public void setOrderField(String order) {
        mOrder = order;
        mChartsQuery = getQuery(mDatabaseRef, mOrder);

        // Set up Recycler Adapter
        FirestoreRecyclerOptions<Chart> recyclerOptions = new FirestoreRecyclerOptions.Builder<Chart>()
                .setQuery(mChartsQuery, Chart.class)
                .build();


        // Use Recycler Adapter in RecyclerView
        mAdapter.setRecyclerOptions(recyclerOptions);

       // then call the notify data set changed on the adapter to recreate the recyclerView elements
       mAdapter.notifyDataSetChanged();
    }

,然后在recyclerView适配器类中,为recyclerOptions添加一个setter:

public void setRecyclerOptions(FirestoreRecyclerOptions<Chart> recyclerOptions) {
       this.recyclerOptions = recyclerOptions;
    }

答案 1 :(得分:0)

发现一个问题...我用以下方法声明了mAdapter

private FirestoreRecyclerAdapter<Chart, ChartViewHolder> mAdapter;

应该在什么时候出现:

private ChartListAdapter mAdapter;

答案 2 :(得分:0)

已解决...在setOrderField中,我在声明一个新的mAdapter,但没有听。一旦添加

mAdapter.startListening()

一切正常!

答案 3 :(得分:0)

2021 年更新:

我不知道这种新方法能用多久,但我很感谢自己找到了它,因为我找不到任何好的回应:

您不再需要在您的适配器中创建任何方法。 只需像这样创建 setOrder 方法:

public FirestoreRecyclerOptions<event_log_Item> getOrder(String order){
    String mOrder = order;
    Query query = current_productRef.orderBy(mOrder, Query.Direction.DESCENDING);
    FirestoreRecyclerOptions<event_log_Item> options = new FirestoreRecyclerOptions.Builder<event_log_Item>().setQuery(query, event_log_Item.class).build();

    return options;
}

此方法将返回您想要的字段的订单选项。

然后简单地做:

mAdapter.updateOptions(setOrder("Timestamp"));
mAdapter.notifyDataSetChanged();

方法 "updateOptions" 已经实现。只需简单地给它你想要的选项并添加 "notifyDataSetChanged();"