我有两个片段FGames和FGamesDetail。显示游戏列表,单击时应填充FGamesDetail片段。我正在使用MVP模式。
我正在尝试为平板电脑实现MultiPane布局,使列表和详细视图彼此相邻。
我在' mListener.onGameSelected(gameEntity)中得到一个空指针异常;'在FGames。我知道我没有在这个地方初始化它,但是我应该按照MVP模式中的每个方法初始化它。
GamesAdapter - RecyclerView Adapter。
@OnClick(R.id.row_container)
void rowClick(){
GamesPresenter gamesPresenter = new GamesPresenterImpl();
gamesPresenter.showGameDetail(data.get(getLayoutPosition()));
Toast.makeText(context, "itemClicked " + data.get(getLayoutPosition()), Toast.LENGTH_SHORT).show();
}
GamesPresenter - 界面
public interface GamesPresenter {
void initUi();
void showGameDetail(GameEntity gameEntity);
}
GamesPresenterImpl -
public class GamesPresenterImpl implements GamesPresenter {
GamesView gamesView;
private ApiInterface apiInterface;
/**
* Collects all subscriptions to unsubscribe later
*/
@NonNull
private CompositeDisposable mCompositeDisposable = new CompositeDisposable();
public GamesPresenterImpl() {}
public GamesPresenterImpl(GamesView gamesView) {
this.gamesView = gamesView;
}
@Override
public void initUi() {
getGamesData();
}
@Override
public void showGameDetail(GameEntity gameEntity) {
//gamesView was null so initialised here
GamesView gamesView = new FGames();
gamesView.onListItemClick(gameEntity);
}
}
GamesView - 界面
public interface GamesView {
/**
* Initialise the recycler view to list Games data
* @param gameEntities
*/
void initRecyclerView(List<GameEntity> gameEntities);
void showToast(String message);
void onListItemClick(GameEntity gameEntity);
}
#
FGames - 拥有Fragment的所有实现
public class FGames extends Fragment implements GamesView {
@BindView(R.id.rv_games)
RecyclerView rvGames;
private GamesAdapter gamesAdapter;
private GamesPresenterImpl presenter;
OnGameSelectedListener mListener;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.games_layout, container, false);
ButterKnife.bind(this, view);
presenter = new GamesPresenterImpl(this);
return view;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
mListener = (OnGameSelectedListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString() + " must implement OnArticleSelectedListener");
}
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
presenter.initUi();
}
@Override
public void initRecyclerView(List<GameEntity> gameEntities) {
gamesAdapter = new GamesAdapter(getActivity(), gameEntities);
rvGames.setAdapter(gamesAdapter);
rvGames.setLayoutManager(new LinearLayoutManager(getActivity()));
}
@Override
public void showToast(String message) {
Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
}
@Override
public void onListItemClick(GameEntity gameEntity) {
//Here is where the NUll pointer exception is
mListener.onGameSelected(gameEntity);
}
public interface OnGameSelectedListener{
public void onGameSelected(GameEntity gameEntity);
}
}
MainActivity - 显示执行游戏选择的操作以在细节片段可用时更新UI。我按照Android文档执行此操作。
public class MainActivity extends AppCompatActivity implements FGames.OnGameSelectedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//FGames fGames = new FGames();
//getSupportFragmentManager().beginTransaction().add(R.id.games_container, fGames).commit();
}
@Override
public void onGameSelected(GameEntity gameEntity) {
FGameDetail gameDetailFrag = (FGameDetail) getSupportFragmentManager()
.findFragmentById(R.id.fragment_fGameDetail);
if (gameDetailFrag == null) {
// DisplayFragment (Fragment B) is not in the layout (handset layout),
} else {
// DisplayFragment (Fragment B) is in the layout (tablet layout),
// so tell the fragment to update
gameDetailFrag.updateContent(gameEntity);
}
}
}
错误日志
Process: com.example.rao.igttest, PID: 21481
java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.rao.igttest.Games.View.FGames$OnGameSelectedListener.onGameSelected(com.example.rao.igttest.Games.Entity.GameEntity)' on a null object reference
at com.example.rao.igttest.Games.View.FGames.onListItemClick(FGames.java:73)
at com.example.rao.igttest.Games.Presenter.GamesPresenterImpl.showGameDetail(GamesPresenterImpl.java:53)
at com.example.rao.igttest.Games.View.GamesAdapter$GamesViewHolder.rowClick(GamesAdapter.java:72)
at com.example.rao.igttest.Games.View.GamesAdapter$GamesViewHolder_ViewBinding$1.doClick(GamesAdapter$GamesViewHolder_ViewBinding.java:33)
at butterknife.internal.DebouncingOnClickListener.onClick(DebouncingOnClickListener.java:22)
at android.view.View.performClick(View.java:5637)
at android.view.View$PerformClick.run(View.java:22429)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)