我正在使用Android Studio。我无法在线找到答案,因此即使是解决方案的链接也将很有帮助。
我有一个Activity
,其中包含许多片段。这些片段之一称为BookGridFragment
,它使用称为BookGrid
的类。
BookGridFragment
看起来像这样(我省略了无关的部分):
public class BookGridFragment extends Fragment {
BookGrid myBookGrid;
public BookGridFragment() {}
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
// Inflate layout
View rootView = inflater.inflate(
R.layout.fragment_book_grid, container, false);
myBookGrid = rootView.findViewById(book_grid);
return rootView;
}
public void setBook(Book thisBook) {
myBookGrid.setBook(thisBook);
}
}
BookGrid
类是:
public class BookGrid extends View {
private Book mBook;
public BookGrid(Context thisContext, AttributeSet attrs) {
super(thisContext, attrs);
}
public void setBook(Book newBook) {
mBook = newBook;
}
protected void onDraw(Canvas canvas) {
if (mBook == null) return;
canvas.save();
draw_book_details();
// draw_book_details() is a function which just takes
// the book info and displays it in a grid
canvas.restore();
}
public boolean onTouchEvent(MotionEvent event) {
// This function responds to the user tapping a piece of
// book info within the grid
// THIS IS WHERE I'M HAVING PROBLEMS
}
}
所以,一切正常。问题是,我需要BookGridFragment知道用户何时触摸BookGrid
并将该信息传递给另一个Fragment
(通过Activity
)。因此,我假设到达onTouchEvent
时,应该以某种方式通知BookGridFragment
BookGrid
被触摸了,但是我不知道该怎么做。
我在网上找到的所有内容都是关于在片段之间传递信息,但是这种方法在这里行不通,因为BookGrid
类并不“知道”它在BookGridFragment
内。
答案 0 :(得分:3)
您可以使用与传达片段和活动相同的想法。创建一个界面:
public interface OnBookGridTouched{
void onTouchGrid();
}
将变量添加到BookGrid:
private OnBookGridTouched mCallback;
向此变量添加一个setter:
public void setCallback(OnBookGridTouched callback){
mCallback = callback;
}
然后使您的片段实现接口:
public class BookGridFragment extends Fragment implements OnBookGridTouched {
您将被迫实施方法onTouchGrid
在片段的onCreateView中,将该片段传递到您的自定义视图:
myBookGrid.setCallback(this);
最后,在您的自定义视图中,您可以调用回调以引用该片段:
public boolean onTouchEvent(MotionEvent event) {
// This function responds to the user tapping a piece of
// book info within the grid
// THIS IS WHERE I'M HAVING PROBLEMS
mCallback.onTouchGrid();
}
答案 1 :(得分:1)
一种解决方案是在片段中而不是BookGrid本身中设置onTouch / onClick侦听器。从那里,您可以使用片段方法getActivity()调用一个活动方法,将正确的数据解析为正确的片段。
答案 2 :(得分:1)
我认为这种情况与包含Fragment
的{{1}}非常相似。
Button
的方法可以接受实现特定接口的内容(对于Button
:Button
)。 View.OnClickListener
调用该方法(用于Button:Fragment
)以传递所需的setOnClickListener()
来实现所有必需的方法,这些方法可以是匿名类,也可以是字段或{{1} }本身。这三种方法各有利弊,这取决于您的情况,哪一种是最佳的。
他们的共同点是Object
应该具有接口和方法,以便其他类可以设置当前的Fragment
来实现该接口。
答案 3 :(得分:1)
我不太确定您在那里遇到的确切情况。但是,如果问题是片段与承载该片段的活动之间的通信,那么您可能会想到以下实现。
首先让我指出您的一些担忧。
我在网上找到的所有内容都是关于在 片段,但是这种方法在这里不能作为BookGrid类使用 不“知道”它在BookGridFragment中。
BookGrid
类将在您调用其函数的同时向其传递Context
时知道其存在的上下文。因此,我建议在从Activity
类调用函数时,传递Fragment
或BookGrid
的上下文。
public class BookGrid extends View {
private Book mBook;
private Context context;
public BookGrid(Context thisContext, AttributeSet attrs) {
super(thisContext, attrs);
this.context = thisContext;
}
public void setBook(Book newBook) {
mBook = newBook;
}
protected void onDraw(Canvas canvas) {
if (mBook == null) return;
canvas.save();
draw_book_details();
// draw_book_details() is a function which just takes
// the book info and displays it in a grid
canvas.restore();
}
public boolean onTouchEvent(MotionEvent event) {
// Call the function of your host activity
((YourActivity)(thisContext)).onBookGridTouched();
}
}
现在在您的活动类中编写一个公共方法,该方法承载名为onBookGridTouched
的片段。
public void onBookGridTouched() {
// Communicate with other fragments here
}
但是,以更通用的方式解决此问题的一种崇高方法是使用interface
,然后在需要时实施interface
,如@LeviAlbuquerque建议的那样。
我只是提出了另一种解决方法,该解决方法有点静态。
答案 4 :(得分:1)
假设您有一个活动负责所有片段:
1。在BookGrid中创建一个接口:
public interface ActionHappened {
void onActionHappened();
}
2。在BookGrid类中创建接口的实例,然后在希望触发它的位置触发onActionHappened方法。例如,如果您希望它在onDraw()中发生,请执行以下操作:
ActionHappened actionHappened;
protected void onDraw(Canvas canvas) {
if (mBook == null) return;
canvas.save();
draw_book_details();
// draw_book_details() is a function which just takes
// the book info and displays it in a grid
canvas.restore();
actionHappened.onActionHappened();
}
3。在活动中添加界面
public class ActivityA extends AppCompatActivity implements BookGrid.ActionHappened {}
4。在已实现的方法中,触发该方法:
@Override
public void onActionHappened() {
Fragment fragmentA = getSupportFragmentManager().findFragmentByTag(R.id.fragmentA);
Fragment fragmentB = getSupportFragmentManager().findFragmentByTag(R.id.fragmentB);
//Trigger that method from your activity to fragmentA or fragmentB
fragmentA.doWork();
fragmentB.doWork();
}
无论您要将数据传递给fragmentA还是fragmentB,doWork()方法都可以为您完成。让您在相应的片段中创建这样的方法。