Переход интерфейса к фрагменту
Рассмотрим случай, когда у меня есть Fragment A
и Fragment B
B
заявляет:
public interface MyInterface {
public void onTrigger(int position);
}
A
реализует этот интерфейс.
При нажатии Fragment B
в стеке, как мне передать ссылку Fragment A
для него в Bundle
чтобы A
мог получить onTrigger
вызов onTrigger
когда это необходимо.
Моим сценарием использования является то, что A
имеет ListView
с элементами, а B
имеет ViewPager
с элементами. Оба содержат одинаковые элементы, и когда пользователь переходит из B → A
перед появлением B
он должен вызвать обратный вызов для A
чтобы обновить его положение ListView
чтобы он соответствовал позиции пейджера B
Благодарю.
Ответы
Ответ 1
Passing interface to Fragment
Я думаю, что вы общаетесь между двумя Fragment
Для этого вы можете взглянуть на Связь с другими фрагментами
public class FragmentB extends Fragment{
MyInterface mCallback;
// Container Activity must implement this interface
public interface MyInterface {
public void onTrigger();
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (MyInterface ) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement MyInterface ");
}
}
...
}
Ответ 2
Для Kotlin 1.0.0-beta-3595
interface SomeCallback {}
class SomeFragment() : Fragment(){
var callback : SomeCallback? = null //some might want late init, but I think this way is safer
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
callback = activity as? SomeCallback //returns null if not type 'SomeCallback'
return inflater!!.inflate(R.layout.frag_some_view, container, false);
}
}
Ответ 3
Оптимальным для двух фрагментов является только общение через активность. Таким образом, вы можете определить интерфейс в Fragment B, который реализован в действии. Затем в действии определите в методе интерфейса то, что вы хотите увидеть в фрагменте A.
В фрагменте B,
MyInterface mCallback;
public interface MyInterface {
void onTrigger(int position);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (MyInterface) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement MyInterface");
}
}
Метод определения, идет ли пользователь от B к A
public void onChangeFragment(int position){
//other logic here
mCallback.onTrigger(position);
}
В действии,
public void onTrigger(int position) {
//Find listview in fragment A
listView.smoothScrollToPosition(position);
}
Удачи!
Ответ 4
Используя @Amit ответ и адаптируясь к вопросу OPs, вот весь соответствующий код:
public class FragmentA extends BaseFragment implements MyInterface {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// THIS IS JUST AN EXAMPLE OF WHERE YOU MIGHT CREATE FragmentB
FragmentB myFragmentB = new FragmentB();
}
void onTrigger(int position){
// My Callback Happens Here!
}
}
...
public class FragmentB extends BaseFragment {
private MyInterface callback;
public interface MyInterface {
void onTrigger(int position);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
callback = (MyInterface ) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement MyInterface");
}
}
}