Как обновить данные, отображаемые в программе recyclerview, которые содержатся во фрагменте из основного действия? (Решена) - PullRequest
0 голосов
/ 02 июля 2019

Я не могу понять, как обновить данные, отображаемые RecyclerView, когда RecyclerView находится во фрагменте. У меня есть ArrayList of Strings, где хранятся элементы, которые я пытаюсь отобразить. Если я предварительно определю список либо в сценарии фрагмента, либо в основной деятельности, в которой размещен фрагмент, он будет отображаться в RecyclerView очень хорошо. Но затем я пытаюсь обновить список во время выполнения, и я полностью потерян. Как мне обновить список во время выполнения ??

В моем приложении я пытаюсь сканировать BT-устройства в этой области и отображать результаты сканирования в этом RecyclerView. Я знаю, что часть сканирования работает нормально, я могу получить ArrayList of Strings, содержащий MAC-адреса всех сканируемых устройств в этой области. Я попытался передать обновленные данные в скрипт Fragment с помощью установщика, но он зависает, когда достигает этой точки в коде.

//This is what I use to define each device    
public class Device{
    private String deviceName;
    public Device(String name){
        this.deviceName = name;
    }
}

//----------------------------------------
//This is the adapter for the RecyclerView
public class deviceAdapter extends RecyclerView.Adapter<deviceAdapter.ViewHolder>{
    private List<Device> deviceList;
    public deviceAdapter(List<Device> deviceList){
        this.deviceList= deviceList;
    }

    //>>>>Data is set here<<<<
    public void setData(List<Device> deviceList) {
        this.deviceList = deviceList;
        notifyDataSetChanged();
    }

    public class ViewHolder extends RecyclerView.ViewHolder{
        public TextView deviceTextView;
        public Button connectButton;
        public ViewHolder(View itemView){
            super(itemView);
            deviceTextView = (TextView) itemView.findViewById(R.id.deviceDescription);
            connectButton = (Button)itemView.findViewById(R.id.connectButton);
        }
    }

    @Override
    public deviceAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Context context = parent.getContext();
        LayoutInflater inflater = LayoutInflater.from(context);
        View deviceItemLayout = inflater.inflate(R.layout.deviceitem, parent, false);
        ViewHolder viewHolder = new ViewHolder(deviceItemLayout);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(deviceAdapter.ViewHolder viewHolder, int position) {
        viewHolder.deviceTextView.setText(deviceList.get(position).getName());
    }

    @Override
    public int getItemCount() {
        return data.length;
    }

//---------------------------------------
//Fragment that contains the RecyclerView
public class HomeFragment extends Fragment {
    private List<Device> deviceList = new ArrayList<>();
    //>>>> Adapter is created here<<<<
    deviceAdapter adapter = new deviceAdapter(deviceList);
    RecyclerView rvDevices;
    public HomeFragment(List<Device> deviceList){
        this.deviceList = deviceList;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        View rootView = inflater.inflate(R.layout.fragment_home, container, false);
        rvDevices = (RecyclerView) rootView.findViewById(R.id.rvDevices);
        rvDevices.setLayoutManager(new LinearLayoutManager(getContext()));
        rvDevices.addItemDecoration(new DividerItemDecoration(rvDevices.getContext(), DividerItemDecoration.VERTICAL));
        //>>>>Adapter is set here<<<<
        rvDevices.setAdapter(adapter);
        rvDevices.setItemAnimator(new DefaultItemAnimator());
        return rootView;
    }

    public void updateFragmentData(List<Device> deviceL){
        this.deviceList = deviceL;
        if(adapter != null){
            adapter.setData(deviceList);
            adapter.notifyDataSetChanged();
        }
    }
}

//-------------------------------------------------
//my main-activity (relevant parts)
public class Interface extends AppCompatActivity {
    //Located at onCreate()
    homeFragment = new HomeFragment(scannedDevicesMAC);
    fragment = homeFragment
    fragmentManager = getSupportFragmentManager();
    fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.frameLayout, fragment);
    fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
    fragmentTransaction.commit();

    tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener(){
        @Override
        public void onTabSelected(TabLayout.Tab tab){
            switch(tab.getPosition()){
                case 0:
                    fragment = homeFragment;
                    break;
                case 1:
                    fragment = new JavaFragment();
                    break;
                case 2:
                    fragment = new AndroidFragment();
                    break;
            }

        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.replace(R.id.frameLayout, fragment);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        ft.commit();
        }
    //...
    });

    final BroadcastReceiver mReceiver = new BroadcastReceiver(){
        @Override
        public void onReceive(Context context, Intent incoming)
        {
            String iAction = incoming.getAction();
            if(BluetoothDevice.ACTION_FOUND.equals(iAction)){
                BluetoothDevice tmpScannedDevices = incoming.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                String tmpMACAddress = tmpScannedDevices.getAddress();
                int tmpRSSI = incoming.getShortExtra(BluetoothDevice.EXTRA_RSSI,Short.MIN_VALUE);
                String tmpDeviceName = tmpScannedDevices.getName();

                scannedDevicesBTOs.add(tmpScannedDevices);
                scannedDevicesMAC.add(new Device(tmpMACAddress));

                //This is the list I'm trying to display
                scannedDevicesList.add("Name: " + tmpDeviceName + " || Address: " + tmpMACAddress + " || RSSI:" + tmpRSSI);   
                if(fragment != null){
                    homeFragment.updateFragmentData(scannedDevicesMAC);
                }
            }
        }
    };

    public void scanDevices(){
        if(mBTAdapter.isEnabled()){
            scannedDevicesList.clear();
            scannedDevicesMAC.clear();
            scannedDevicesBTOs.clear();
            if(mBTAdapter.isDiscovering()){
                mBTAdapter.cancelDiscovery();
            }
            Log.d("scanDevices|scanDevices", "Scanning for BT devices");
            mBTAdapter.startDiscovery();
    }
}

Как уже упоминалось, я ожидаю, что RecyclerView, который содержится во фрагменте, будет отображать содержимое ArrayList of Strings, который обновляется из основной деятельности. Я нахожусь в конце своей линии, пытаясь выяснить это в течение нескольких дней!

1 Ответ

0 голосов
/ 02 июля 2019

В вашем Fragment создайте функцию ниже

public void updateFragmentData(Device[] data){
  this.data = data;
  if(adapter != null){
    adapter.setData(data);
    adapter.notifyDataSetChanged();
  }
}

и затем с вашего Activity звонка

if(fragment != null){
   fragment.updateFragmentData(data);
}

Выше приведено быстрое решение. Еще лучше было бы использовать интерфейсы для обновления fragment.

Обновлено

В своей деятельности вы должны объявить эти три

HomeFragment homeFragment;
JavaFragment javaFragment;
AndroidFragment androidFragment;

и затем в onCreate() инициализируем их

homeFragment = new HomeFragment(data);
javaFragment = new JavaFragment();
androidFragment = new AndroidFragment();

и тогда вам нужно обновить только homeFragment, чтобы код выглядел следующим образом

if(homeFragment != null){
  homeFragment.updateFragmentData(data);
}


public void setData(List<Device> deviceList) {
    this.deviceList.clear;
    this.deviceList.addAll(deviceList);

    notifyDatasetChanged();
}

Так что теперь вам не нужно уведомлять DataSetChanged в вашем фрагменте.

...