【问题标题】:RecyclerView don't show items even if I call notifyDataSetChanged()即使我调用 notifyDataSetChanged(),RecyclerView 也不显示项目
【发布时间】:2022-01-29 10:50:19
【问题描述】:

我正在使用 RecyclerView 来显示数据,但即使我在从 Room db 获得列表后调用 notifyDataSetChanged() 我也看不到第一次创建片段时的项目,但只有第二个。

MainActivity.class

package it.bastoner.taboom;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.MenuItem;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.room.Room;

import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationBarView;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import it.bastoner.taboom.database.CardDAO;
import it.bastoner.taboom.database.CardEntity;
import it.bastoner.taboom.database.DatabaseTaboom;
import it.bastoner.taboom.fragments.AddFragment;
import it.bastoner.taboom.fragments.BaseCardFragment;
import it.bastoner.taboom.fragments.PlayFragment;
import it.bastoner.taboom.fragments.UpdateFragment;

public class MainActivity extends AppCompatActivity {

private static final String TAG = "MainActivity";
private List<CardEntity> cardList;
private boolean cardListIsUpdated;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Log.d(TAG, ">>MainActivity created");

    cardList = new ArrayList<CardEntity>();

    // Setting bottomNavigation
    BottomNavigationView bottomNav = findViewById(R.id.bottom_nav);
    bottomNav.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {

        //TODO ANIMATION

        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {

            // By using switch we can easily get the selected fragment by using there id.
            Fragment selectedFragment = null;
            switch (item.getItemId()) {
                case R.id.add_nav:
                    selectedFragment = new AddFragment(cardList);
                    break;
                case R.id.play_nav:
                    selectedFragment = new PlayFragment(cardList);
                    break;
                case R.id.update_nav:
                    selectedFragment = new UpdateFragment(cardList);
                    break;
            }
            // It will help to replace the
            // one fragment to other.
            getSupportFragmentManager()
                    .beginTransaction()
                    .replace(R.id.fragment_container, selectedFragment)
                    .commit();
            return true;
        }

    });

    // As soon as the application opens the play fragment should be shown to the user
    bottomNav.setSelectedItemId(R.id.play_nav);

    loadCardList();

}

private void loadCardList() {

    CardDAO cardDAO = DatabaseTaboom.getDatabase(getApplicationContext()).cardDao();

    // Setting cardsList
    ExecutorService executor = Executors.newSingleThreadExecutor();

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            cardList = cardDAO.getAll();
            Log.d(TAG, ">>Cardlist: " + cardList);
            BaseCardFragment actualFragment = (BaseCardFragment) getSelectedFragment();
            if (actualFragment != null)
                actualFragment.updateUI();
            else
                Log.d(TAG, ">>Null fragment");
        }
    };

    executor.execute(runnable);

}

private Fragment getSelectedFragment() {

    FragmentManager fragmentManager = getSupportFragmentManager();
    List<Fragment> fragmentList = fragmentManager.getFragments();
    for (Fragment f: fragmentList) {
        if (f != null && f.isVisible())
            return f;
    }
    return null;
}

}

PlayFragment.class

package it.bastoner.taboom.fragments;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.media.MediaPlayer;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.PagerSnapHelper;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SnapHelper;

import android.os.CountDownTimer;
import android.text.InputFilter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;
import java.util.Locale;

import it.bastoner.taboom.R;
import it.bastoner.taboom.adapter.RecyclerViewAdapter;
import it.bastoner.taboom.database.CardEntity;
import it.bastoner.taboom.filters.MinMaxFilter;
import it.bastoner.taboom.listeners.MyDialogListener;


public class PlayFragment extends BaseCardFragment implements MyDialogListener {

    private static final String TAG = "PlayFragment";

    private RecyclerView recyclerView;

    private TextView timerTextView;
    private Button playPauseButton;
    private Button resetButton;
    private CountDownTimer countDownTimer;
    private long startTimeInMillis;
    private boolean timerIsRunning;
    private long timeLeftInMillis = startTimeInMillis;

    private MediaPlayer endTimerSound;

    public PlayFragment(List<CardEntity> cardList) {
        super(cardList);
        //Log.d(TAG, "PlayFragment created");
    }

    @Override
    public void updateUI() {
        recyclerView.getAdapter().notifyDataSetChanged();
        Log.d(TAG, ">>Update, number of items: " + recyclerView.getAdapter().getItemCount());
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        Log.d(TAG, ">>OnCreateView");
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_play, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        Log.d(TAG, ">>OnViewCreated");

        setRecyclerView();

        setTimerSound();

        setTimer();

        setDialogModifyTimer();

        updateUI();

    }

   // other methods...

}

正如您在控制台 中看到的那样,cardList 在调用 UpdateUI() 之前已接收到元素,但在第一次调用更新时没有元素被调用见过。你能帮助我吗?我不明白为什么,谢谢。

【问题讨论】:

    标签: java android android-recyclerview android-room


    【解决方案1】:

    我认为您需要在 RecyclerAdapter 中设置数据。然后使用 ViewModel 在您的片段中调用它。对不起,我正在使用 Kotlin。 仅当您将 RoomDB 与 viewModel 和存储库一起使用时,这才有效

    在你的 RecyclerAdapter 中,你首先需要设置一个空列表

    
    private var timerList = emptyList<EntityClassName>()
        
        // Now use a method to set the Data
        fun setData(timer : List<EntityClassName>){
            this.timerList = timer
            notifyDataSetChanged()
        }
    
    

    然后你在 OnViewCreated 中的 Fragment 上调用它。

    sharedViewModel.readAllData.observe(viewLifecycleOwner,Observer {
                data -> myAdapter.setData(data)}) 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-01
      • 1970-01-01
      • 2017-02-24
      • 2019-05-25
      • 1970-01-01
      • 1970-01-01
      • 2019-10-14
      相关资源
      最近更新 更多