Как установить интерфейс, идентификатор которого содержится в обычном классе (не activity)

#android #android-fragments #interface

#Android #android-фрагменты #интерфейс

Вопрос:

Я использую приложение, которое содержит viewPager и TapLayout . И фрагмент, который отображается на ViewPager, имеет Bluetooth функцию подключения. Когда я нажимаю кнопку на фрагменте, запускается Ble. Но в этом процессе я получил

ошибка ClassCastException интерфейса

Фрагмент реализует интерфейс, который в BluetoothController. BluetoothController нужен контекст, поэтому я передал context (getContext), который попал во фрагмент. Когда я реализую интерфейс и передаю контекст в MainActivity, он работает хорошо. Но я делаю это во фрагменте, в Android studio возникает ошибка «Ошибка исключения класса интерфейса». Я должен реализовать интерфейс во фрагменте, потому что интерфейс передает состояние Bluetooth, например, подключение, отключение, запуск и т.д. Как я могу установить интерфейс во фрагменте?

Когда MainActivity реализует интерфейс, интерфейс Bluetooth работает хорошо. Но в этом случае состояние Bluetooth не передается во фрагменте. Он передает состояние в MainActivity. Я думаю, что когда я получаю состояние в MainActivity, передача состояния фрагменту является одним из решений этой проблемы. Но я думаю, что это не очень хороший метод.

вот код BluetoothContoller

 public class BluetoothController extends BluetoothPacketController
{
    public static final String TAG = BluetoothController.class.getSimpleName()  "_Debug";

    private static Context context;

    private static final int SCAN_PERIOD = 1000*10;

    private int BLE_STATE = BLUETOOTH_STATE.IDLE;
    private BleInterface mListener;

    public class BLUETOOTH_STATE {
        public static final int IDLE = 0;
        public static final int SCANNING = 1;
        public static final int CONNECTION_TRY = 2;
        public static final int CONNECTION_ERR = 3;
        public static final int CONNECTION_SUCC = 4;
        public static final int DISCONNECTION = 5;
    }

    public interface BleInterface{
        void bleScanTimeOut();
        void bleScanStart();
        void bleScanStop();
        void bleConnectTry();
        void bleDisConnectTry();
        void bleErrDisConnectTry();
        void bleDisConnected();
        void bleResult(boolean ret);
        void bleResult(String ret);
    }

    private static BluetoothController instance = null;


    @Override
    public void setContext(Context context) {
        super.setContext(context);
        this.context = context;

    }

    public static BluetoothController getInstance() {
        if (instance == null) {
            instance = new BluetoothController();

        }

        return instance;
    }

    @Override
    public void init(Context context) {
        super.init(context);
        setContext(context);
        mListener = (BluetoothController.BleInterface) context;//listener;//(BluetoothController.BleInterface) context;

    }
    ...
}
  

И вот фрагмент кода

 public class RegistrationFragment extends Fragment implements BluetoothController.BleInterface{

    private View view;
    public static final String TAG = RegistrationFragment.class.getSimpleName()   "_Debug";

    private static RegistrationFragment instance = null;

    public static RegistrationFragment getInstance() {
        if (instance == null) {
            instance = new RegistrationFragment();
        }
        return instance;
    }

    public void setContext(Context context) {
        this.context = context;
    }

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

        view = inflater.inflate(R.layout.register_view, container, false);

        BluetoothScanUpperAPI21.getInstance().init(getContext());
        BluetoothScanUnderAPI21.getInstance().init(getContext());
        BluetoothController.getInstance().init(getContext());

        startUi_init();

        return view;
    }
    ...
}
  

Я хочу получить состояние Bluetooth через BleInterface во фрагменте.

Ответ №1:

Почему вы вводите кастинг context BleInterface ? Разве вы не можете перейти this от фрагмента к BluetoothController месту this ссылки BleInterface , которое реализовано во фрагменте?

Во фрагменте

 BluetoothController.getInstance().init(this);
  

Инициализация BleController:

  @Override
    public void init(BluetoothController.BleInterface ble) {
        super.init(context);
        setContext(context);
        mListener = ble;
    }
  

Причина поведения, с которым вы сталкиваетесь:
Фрагмент не имеет собственного контекста. Они всегда ссылаются на контекст активности. Итак, когда вы проходите getContext() , он ссылается на контекст activity, и компилятор пытается найти BleInterface в activity то, чего не существует. Вот почему вы столкнулись ClassCastException .

Комментарии:

1. Я вижу, что сталкиваюсь с этой проблемой. Но я не могу понять ‘BluetoothController.getInstance().init(this);’Вы сказали, что фрагмент не имеет собственного контекста. Поэтому я не могу ввести «это». И причина, по которой я использую контекст, заключается в том, что приложение имеет пять фрагментов, и два из них имеют функцию Bluetooth. Поэтому мой слушатель должен различать, какой фрагмент использует функцию Bluetooth. И я тоже не могу понять инициализацию BleController. Но точно понимаю, почему возникла эта проблема. Спасибо!

2. @youngtaek this будет ссылаться на объект интерфейса, который вы реализовали во фрагменте. Итак, в каждом фрагменте реализуйте интерфейс, а затем передайте this метод init. Вы получите отдельные события в отдельных фрагментах. Это эквивалентно передаче любой переменной в метод.