我是Android开发的新手,我正在使用此代码实现适配器和fragmnet之间的回调。
BookAdapter
public class BookAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private OnButtonClickListener onButtonClickListener;
//List of books
private List<BookItems> mBookItems;
private final int VIEW_ITEM = 0;
private final int VIEW_PROG = 1;
private int lastPosition = -1;
public void OnButtonClickListener (OnButtonClickListener onButtonClickListener) {
this.onButtonClickListener = onButtonClickListener;
}
public interface OnButtonClickListener {
void onButtonClick();
}
public BookAdapter(List<BookItems> bookItems, Context context) {
super();
//Getting all books
this.mBookItems = bookItems;
this.mContext = context;
}
@Override
public int getItemViewType(int position) {
if (isPositionItem(position))
return VIEW_ITEM;
return VIEW_PROG;
}
private boolean isPositionItem(int position) {
return position != getItemCount()-1;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder (ViewGroup parent, int viewType) {
if (viewType == VIEW_ITEM) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.book_summ, parent, false);
return new TextViewHolder(v);
} else if (viewType == VIEW_PROG){
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recyclerfooter, parent, false);
return new ProgressViewHolder(v);
}
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof TextViewHolder) {
final BookItems bookList = mBookItems.get(position);
/...
} else {
((ProgressViewHolder) holder).progressBar.setIndeterminate(true);
((ProgressViewHolder) holder).loadButton.setText(R.string.reload);
}
}
@Override
public int getItemCount(){
//Return the number of items in the data set
return mBookItems.size();
}
public class TextViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
...
}
public class ProgressViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
Button loadButton;
ProgressBar progressBar;
public ProgressViewHolder(View footerView){
super(footerView);
...
}
@Override
public void onClick(View v) {
if (v.getId() == loadButton.getId()) {
onButtonClickListener.onButtonClick();
}
}
}
}
BookFragment
public class BookFragment extends Fragment implements BookAdapter.OnButtonClickListener{
BookAdapter mAdapter;
//Creating a list of books
private List<BookItems> mBookItemsList;
//Creating Views
ObservableRecyclerView recyclerView;
private String title;
private RecyclerView.Adapter adapter;
private ProgressDialog mProgressDialog;
SwipeRefreshLayout mSwipeRefreshLayout;
LinearLayoutManager mLayoutManager;
public BookFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAdapter = new BookAdapter(mBookItemsList,getContext());
mAdapter.OnButtonClickListener(this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
title = getArguments().getString("title");
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_book, container, false);
//Initializing Views
...
return view;
}
...
@Override
public void onButtonClick() {
Log.d(TAG, "I recieved it Sir");
Toast.makeText(getActivity(), "blag blag", Toast.LENGTH_SHORT).show();
}
}
每次点击loadButton
时,应用程序都会因nullpointer异常而崩溃。
你知道为什么会发生这种情况以及如何纠正这个问题吗?
05-21 01:34:17.710 20717-20717/com.myapp.bookman E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.myapp.bookman, PID: 20717
java.lang.NullPointerException: Attempt to invoke interface method 'void com.myapp.bookman.BookAdapter$OnButtonClickListener.onButtonClick()' on a null object reference
at com.myapp.bookman.BookAdapter$ProgressViewHolder.onClick(BookAdapter.java:251)
at android.view.View.performClick(View.java:5076)
at android.view.View$PerformClick.run(View.java:20279)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5910)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
在堆栈跟踪行251中, BookAdapter
中的行onButtonClickListener.onButtonClick();
BookAdapter
public class BookAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
//List of books
private List<BookItems> mBookItems;
private final int VIEW_ITEM = 0;
private final int VIEW_PROG = 1;
private int lastPosition = -1;
public void OnButtonClickListener (OnButtonClickListener onButtonClickListener) {
this.onButtonClickListener = onButtonClickListener;
}
public interface OnButtonClickListener {
void onButtonClick();
}
public BookAdapter(List<BookItems> bookItems, Context context) {
super();
//Getting all books
this.mBookItems = bookItems;
this.mContext = context;
}
@Override
public int getItemViewType(int position) {
if (isPositionItem(position))
return VIEW_ITEM;
return VIEW_PROG;
}
private boolean isPositionItem(int position) {
return position != getItemCount()-1;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder (ViewGroup parent, int viewType) {
if (viewType == VIEW_ITEM) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.book_summ, parent, false);
return new TextViewHolder(v);
} else if (viewType == VIEW_PROG){
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recyclerfooter, parent, false);
return new ProgressViewHolder(v);
}
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof TextViewHolder) {
final BookItems bookList = mBookItems.get(position);
/...
} else {
((ProgressViewHolder) holder).progressBar.setIndeterminate(true);
((ProgressViewHolder) holder).loadButton.setText(R.string.reload);
}
}
@Override
public int getItemCount(){
//Return the number of items in the data set
return mBookItems.size();
}
public class TextViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
...
}
public class ProgressViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
Button loadButton;
ProgressBar progressBar;
public ProgressViewHolder(View footerView){
super(footerView);
...
}
@Override
public void onClick(View v) {
if (v.getId() == loadButton.getId()) {
onButtonClickListener.onButtonClick();
}
}
}
}
BookFragment
public class BookFragment extends Fragment implements BookAdapter.OnButtonClickListener{
BookAdapter mAdapter;
//Creating a list of books
private List<BookItems> mBookItemsList;
//Creating Views
ObservableRecyclerView recyclerView;
private String title;
private RecyclerView.Adapter adapter;
private ProgressDialog mProgressDialog;
SwipeRefreshLayout mSwipeRefreshLayout;
LinearLayoutManager mLayoutManager;
public BookFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAdapter = new BookAdapter(mBookItemsList,getContext());
mAdapter.OnButtonClickListener(this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
title = getArguments().getString("title");
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_book, container, false);
//Initializing Views
...
return view;
}
...
OnButtonClickListener onButtonClickListener = new OnButtonClickListener() {
@Override
public void onButtonClick() {
Log.d(TAG, "I recieved it Sir");
Toast.makeText(getActivity(), "blag blag", Toast.LENGTH_SHORT).show();
}
}
}
问题是 BookAdapter 中onButtonClickListener
行this.onButtonClickListener = onButtonClickListener;
,Android工作室说“无法解析onButtonClickListener上的符号”
而且,在 BookFragment 中,在行public class BookFragment extends Fragment implements BookAdapter.OnButtonClickListener
中我要么声明类抽象,要么在OnButtonClickListener中实现onButtoClick()。
答案 0 :(得分:0)
您创建了private OnButtonClickListener onButtonClickListener;
,但它永远不会被分配,所以当您致电onButtonClickListener.onButtonClick();
时,它会给出一个NPE。
在 BookAdapter 中,替换
private OnButtonClickListener onButtonClickListener;
与
OnButtonClickListener onButtonClickListener = new OnButtonClickListener(){
@Override
public void onButtonClick(){
//Do stuff
}
};