RecylerView不会填充

时间:2015-11-30 21:36:04

标签: java android sqlite android-recyclerview

调试后的更新

事实证明convertCursorToTransactionInfoListtransactionLoadComplete实际上从未运行过。我在它们上面放了断点,它们从未出现在调试器中。此外,运行调试器时会显示adapterData: size = 0

我能够使用onCreateViewTransactionInfo returnListValue = new TransactionInfo();下的代码正确填充回收站视图的一个项目

任何人都可以提供一些有关为什么这不起作用的见解?我越来越多地这样做,我认为它与ArrayList<>List<>差异有关,因为ArrayList<>用于TransactionsTab.javaAdapterTransactions.javaList<> },TransactionInfo.java在某些方面使用 OR Spinners。我在下面发布了所有这些课程。

SQLite界面不是问题(我很确定),因为我在应用程序的其他地方使用它来使用SimpleCursorAdapter填充public class TransactionsTab extends Fragment implements TransactionLoad.LoadComplete { RecyclerView transactionsRecycler; AdapterTransactions adapter; TransactionLoad load = null; Cursor cursor; ArrayList<TransactionInfo> adapterData = new ArrayList<>(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); load = new TransactionLoad(getActivity()); load.execute(); } @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.tab_transactions,container,false); transactionsRecycler = (RecyclerView) view.findViewById(R.id.transactionRecycler); adapter = new AdapterTransactions(getActivity(), adapterData); transactionsRecycler.setAdapter(adapter); transactionsRecycler.setLayoutManager(new LinearLayoutManager(getActivity())); TransactionInfo returnListValue = new TransactionInfo(); returnListValue.itemName = "lunch"; returnListValue.itemCat = "Food"; returnListValue.itemCurrency = "KRW"; returnListValue.itemPrice = "125"; returnListValue.date = "2015/08/25; 17:25:32"; adapterData.add(returnListValue); return view; } private void convertCursorToTransactionInfoList(Cursor cursor) { if (cursor != null) { while (cursor.moveToNext()) { TransactionInfo returnListValue = new TransactionInfo(); returnListValue.itemName = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_NAME)); returnListValue.itemCat = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_CATEGORY)); returnListValue.itemCurrency = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_CURRENCY)); returnListValue.itemPrice = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_PRICE)); returnListValue.date = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_DATE)); adapterData.add(returnListValue); } } } @Override public void transactionLoadComplete(Cursor cursor) { convertCursorToTransactionInfoList(cursor); adapter.setData(adapterData); adapter.notifyDataSetChanged(); adapter.transactionData.notifyAll(); } }

TransactionsTab.java:

public class AdapterTransactions extends RecyclerView.Adapter<AdapterTransactions.MyViewHolder> {

private LayoutInflater inflater;
List<TransactionInfo> transactionData = Collections.emptyList();

public void setData(List<TransactionInfo> newData) {
    transactionData = newData;
}

public AdapterTransactions(Context context, List<TransactionInfo> transactionData) {
    inflater = LayoutInflater.from(context);
    this.transactionData = transactionData;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = inflater.inflate(R.layout.transaction_row, parent, false);
    MyViewHolder holder = new MyViewHolder(view);
    return holder;
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
    TransactionInfo current = transactionData.get(position);
    holder.itemName.setText(current.itemName);
    holder.itemCat.setText(current.itemCat);
    holder.itemPrice.setText(current.itemPrice);
    holder.itemDate.setText(current.date);
    holder.itemCurrency.setText(current.itemCurrency);
}

@Override
public int getItemCount() {
    return transactionData.size();
}

class MyViewHolder extends RecyclerView.ViewHolder {
    TextView itemName, itemCat, itemPrice, itemDate, itemCurrency;

    public MyViewHolder(View itemView) {
        super(itemView);
        itemName = (TextView) itemView.findViewById(R.id.itemName);
        itemCat = (TextView) itemView.findViewById(R.id.itemCat);
        itemPrice = (TextView) itemView.findViewById(R.id.itemPrice);
        itemDate = (TextView) itemView.findViewById(R.id.itemDate);
        itemCurrency = (TextView) itemView.findViewById(R.id.itemCurrency);
    }
}
}

AdapterTransactions.java:

public class TransactionInfo {
public String itemName, itemPrice, itemCurrency, itemCat, date;
}

TransactionInfo.java:

convertCursorToTransactionInfoList

RE ANSWERS:

我已尝试对private void convertCursorToTransactionInfoList(Cursor cursor) { if (cursor != null) { while (cursor.moveToNext()) { TransactionInfo returnListValue = new TransactionInfo(); returnListValue.itemName = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_NAME)); returnListValue.itemCat = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_CATEGORY)); returnListValue.itemCurrency = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_CURRENCY)); returnListValue.itemPrice = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_PRICE)); returnListValue.date = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_DATE)); adapterData.add(returnListValue); } } } 进行以下方法更改:

private static void convertCursorToTransactionInfoList(Cursor cursor, ArrayList<TransactionInfo> adapterData) {
    if (cursor != null) {
        while (cursor.moveToNext()) {
            TransactionInfo returnListValue = new TransactionInfo();
            returnListValue.itemName = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_NAME));
            returnListValue.itemCat = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_CATEGORY));
            returnListValue.itemCurrency = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_CURRENCY));
            returnListValue.itemPrice = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_PRICE));
            returnListValue.date = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_DATE));
            adapterData.add(returnListValue);
        }
    }
}

@Override
public void transactionLoadComplete(Cursor cursor) {
    convertCursorToTransactionInfoList(cursor, adapterData);
    adapter.setData(adapterData);
    adapter.notifyDataSetChanged();
    adapter.transactionData.notifyAll();
}

通知这样的adatpers:

List<TransactionInfo> adapterData = new ArrayList<>();

另外,请注意,我必须将ArrayList<TransactionInfo> adapterData = new ArrayList<>();更改为ArrayList<>

我认为越多,我认为它与List<>library(lubridate) x <- "4:04.86" period_to_seconds(ms(x)) # [1] 244.9 问题有关。

结束编辑

3 个答案:

答案 0 :(得分:2)

问题在于将数据从Cursor中取出,特别是在这里:

if (cursor.moveToFirst()) {
    for (int i = 10; i < cursor.getCount(); i++) {
        returnListValue.itemName = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_NAME));
        returnListValue.itemCat = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_CATEGORY));
        returnListValue.itemCurrency = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_CURRENCY));
        returnListValue.itemPrice = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_PRICE));
        returnListValue.date = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_DATE));
        returnList.add(returnListValue);
    }
}

上面的代码将光标移动到第一个位置(cursor.moveToFirst()),但之后Cursor位置没有改变,所以你的循环执行cursor.getCount()次,但它只是对光标中的第一项进行操作。

相反,我会选择while循环而不是for循环,如下所示:

// move cursor on to next position if available
while(cursor.moveToNext()) { 
    // More data is available so add it to the list
    // process data as before
}

编辑1

RE your comment - 这就是我建议改变的地方。

而不是:

adapterData = convertCursorToBudgetInfoList(cursor);

或者:

选项1

convertCursorToBudgetInfoList仍为static方法,但现在对原始adapterData引用进行操作。

convertCursorToBudgetInfoList(cursor, adapterData);

并将您的方法更改为:

private static void convertCursorToBudgetInfoList(Cursor cursor, ArrayList<TransactionInfo> adapterData) {

    if (cursor != null) {                         

        while (cursor.moveToNext()) { // note: no for loop ;-)
            TransactionInfo returnListValue = new TransactionInfo();
            returnListValue.itemName = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_NAME));
            returnListValue.itemCat = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_CATEGORY));
            returnListValue.itemCurrency = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_CURRENCY));
            returnListValue.itemPrice = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_PRICE));
            returnListValue.date = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_DATE));
            adapterData.add(returnListValue);
        }
    }
}

选项2

convertCursorToBudgetInfoList设为成员方法而非静态方法,并直接对adapterData进行操作。

convertCursorToBudgetInfoList(cursor);

并将您的方法更改为:

private void convertCursorToBudgetInfoList(Cursor cursor) {

    if (cursor != null) {                         

        while (cursor.moveToNext()) { // note: no for loop ;-)
            TransactionInfo returnListValue = new TransactionInfo();
            returnListValue.itemName = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_NAME));
            returnListValue.itemCat = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_CATEGORY));
            returnListValue.itemCurrency = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_CURRENCY));
            returnListValue.itemPrice = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_PRICE));
            returnListValue.date = cursor.getString(cursor.getColumnIndex(DatabaseHelper.TRANSACTION_DATE));
            adapterData.add(returnListValue); // member variable (same as this.adapterData)
        }
    }
}

当然,使用这些选项中的任何一个都要确保通知您的适配器。

我还要重申,你真的需要摆脱那个for循环 - 用调试器逐步完成它,一切都会变得清晰。

答案 1 :(得分:1)

尝试更改for中的convertCursorToBudgetInfoList循环:

for (int i = 10; i < cursor.getCount(); i++) 

0开始...如果少于10个结果,则不会显示任何内容!

答案 2 :(得分:1)

问题在于TransactionsTab。在transactionLoadComplete(Cursor游标)方法中,您更新了Fragments List transactionData,但您从未将其传递到RecyclerView适配器。因此,在适配器上调用notify不会产生任何影响,因为它的数据没有更改。

您的解决方案是在适配器中创建一个功能,例如:

public void setData(List<TransactionData> newData){
    transactionData = newData;
}

然后在transactionLoadComplete(Cursor cursor)中的notifyDataSetChanged之前调用new函数:

public void transactionLoadComplete(Cursor cursor) {
    adapterData = convertCursorToBudgetInfoList(cursor);
    adapter.setData(adapterData);
    adapter.notifyDataSetChanged();
    adapter.transactionData.notifyAll();
}