我想打開一個url鏈接,當我點擊一個回收站中的列表項時,但我一直得到NullPointerException
。我正在使用ViewPager,我不知道這是否是異常的原因,也許我做錯了什麼。請查看我的代碼和下面的logcat。OnItemClickListener在ViewPager中的RecyclerView
這是我的適配器:
public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.NewsHolder> {
private ArrayList<News> mNews = new ArrayList<>();
private static ClickListener clickListener;
public NewsAdapter(ArrayList<News> news) {
mNews = news;
}
private static String timeConverter(String inputTime) {
long startTime = 0;
SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
simpleDate.setTimeZone(TimeZone.getTimeZone("GMT"));
try {
Date date = simpleDate.parse(inputTime);
startTime = date.getTime();
} catch (ParseException e) {
e.printStackTrace();
}
long currentTime = System.currentTimeMillis();
long end = currentTime - startTime;
long seconds = TimeUnit.MILLISECONDS.toSeconds(end);
long minutes = TimeUnit.SECONDS.toMinutes(seconds);
long hours = TimeUnit.MINUTES.toHours(minutes);
if (minutes > 59) {
return hours + "h";
}else if (seconds > 59) {
return minutes + "m";
}else {
return seconds + "s";
}
}
@Override
public NewsHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_view, parent, false);
return new NewsHolder(view);
}
@Override
public void onBindViewHolder(NewsHolder holder, int position) {
String imagePath = mNews.get(position).getImageUrl();
Picasso.with(holder.mImageView.getContext()).load(imagePath).into(holder.mImageView);
holder.mNewsTextView.setText(mNews.get(position).getNews());
holder.mTimeStampTextView.setText(timeConverter(mNews.get(position).getTime()));
}
@Override
public int getItemCount() {
return mNews.size();
}
// NewsHolder class that extends the ViewHolder
public static class NewsHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private ImageView mImageView;
private TextView mNewsTextView;
private TextView mTimeStampTextView;
// Setting the views
public NewsHolder(View itemView) {
super(itemView);
mImageView = (ImageView) itemView.findViewById(R.id.simple_imageView);
mNewsTextView = (TextView) itemView.findViewById(R.id.news_tv);
mTimeStampTextView = (TextView) itemView.findViewById(R.id.time_tv);
}
@Override
public void onClick(View view) {
clickListener.onItemClick(getAdapterPosition(), view);
}
}
public void setOnItemClickListener(ClickListener listener) {
NewsAdapter.clickListener = listener;
}
public interface ClickListener {
void onItemClick(int position, View v);
}
}
這是我ViewPager片段之一:
public class TechFragment extends Fragment {
private SwipeRefreshLayout mSwipeRefreshLayout;
private TextView mErrorMessage;
private NewsAdapter mNewsAdapter;
ArrayList<News> news;
NetworkInfo info;
// The Loader takes in a bundle
Bundle sourceBundle = new Bundle();
private final String LOG_TAG = MainActivity.class.getSimpleName();
private static final String TECH_NEWS_QUERY_URL = "query";
private static final String TECH_NEWS_SOURCE = "techcrunch";
private static final String TECH_SOURCE_CATEGORY = "latest";
private static final int TECH_NEWS_LOADER = 22;
private RecyclerView mRecyclerView;
public TechFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_news, container, false);
mErrorMessage = (TextView) view.findViewById(R.id.tv_error_message);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view_main);
mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeRefresh);
getActivity().getSupportLoaderManager().initLoader(TECH_NEWS_LOADER, sourceBundle, new NewsDataLoader());
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
Log.v(LOG_TAG, "Refreshing");
restartLoader();
mSwipeRefreshLayout.setColorSchemeResources(
R.color.colorPrimary,
R.color.colorPrimaryDark);
}
});
return view;
}
private boolean isConnected() {
ConnectivityManager cm = (ConnectivityManager) getActivity()
.getSystemService(CONNECTIVITY_SERVICE);
info = cm.getActiveNetworkInfo();
return info != null && info.isConnectedOrConnecting();
}
private int anyRandomInt(Random random) {
return random.nextInt();
}
private void restartLoader() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
URL techNewsUrl = NetworkUtils.buildUrl(TECH_NEWS_SOURCE, TECH_SOURCE_CATEGORY);
sourceBundle.putString(TECH_NEWS_QUERY_URL, techNewsUrl.toString());
Random random = new Random();
int uniqueId = anyRandomInt(random); //Generates a new ID for each loader call;
LoaderManager loaderManager = getActivity().getSupportLoaderManager();
if (loaderManager.getLoader(TECH_NEWS_LOADER) == null) {
loaderManager.initLoader(uniqueId, sourceBundle, new NewsDataLoader());
} else {
loaderManager.restartLoader(TECH_NEWS_LOADER, sourceBundle, new
NewsDataLoader());
}
}
}, 5000);
mSwipeRefreshLayout.setRefreshing(false);
Log.v(LOG_TAG, "Finished refreshing");
}
private void showErrorScreen() {
mErrorMessage.setVisibility(View.VISIBLE);
mRecyclerView.setVisibility(View.INVISIBLE);
mErrorMessage.setText(getString(R.string.internet_error));
}
public class NewsDataLoader implements LoaderManager.LoaderCallbacks<ArrayList<News>> {
@Override
public Loader<ArrayList<News>> onCreateLoader(int id, final Bundle args) {
if (isConnected()) {
mErrorMessage.setVisibility(View.INVISIBLE);
mRecyclerView.setVisibility(View.VISIBLE);
return new AsyncTaskLoader<ArrayList<News>>(getActivity()) {
ArrayList<News> mNewsData;
@Override
protected void onStartLoading() {
super.onStartLoading();
if (mNewsData != null) {
deliverResult(mNewsData);
} else {
forceLoad();
mSwipeRefreshLayout.setRefreshing(true);
}
}
@Override
public ArrayList<News> loadInBackground() {
try {
ArrayList<News> news = NetworkUtils.parseJSON(TECH_NEWS_SOURCE, TECH_SOURCE_CATEGORY);
return news;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public void deliverResult(ArrayList<News> data) {
mNewsData = data;
super.deliverResult(data);
}
};
} else {
showErrorScreen();
return null;
}
}
@Override
public void onLoadFinished(Loader<ArrayList<News>> loader, final ArrayList<News> data) {
mSwipeRefreshLayout.setRefreshing(false);
if (null == data) {
showErrorScreen();
} else {
mErrorMessage.setVisibility(View.INVISIBLE);
mRecyclerView.setVisibility(View.VISIBLE);
if (news != null) {
news.clear();
news.addAll(data);
mNewsAdapter = new NewsAdapter(news);
mRecyclerView.setAdapter(mNewsAdapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
mNewsAdapter.notifyDataSetChanged();
} else {
news = data;
}
}
mNewsAdapter.setOnItemClickListener(new NewsAdapter.ClickListener() {
@Override
public void onItemClick(int position, View v) {
News currentNews = news.get(position);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(currentNews.getUrl()));
if (intent.resolveActivity(getActivity().getPackageManager()) != null){
startActivity(intent);
}
}
});
}
@Override
public void onLoaderReset(Loader<ArrayList<News>> loader) {
}
}
}
這是我的錯誤:
06-13 12:11:38.667 3890-3890/com.ire.blogbot E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ire.blogbot, PID: 3890
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.ire.blogbot.adapter.NewsAdapter.setOnItemClickListener(com.ire.blogbot.adapter.NewsAdapter$ClickListener)' on a null object reference
at com.ire.blogbot.fragments.TechFragment$NewsDataLoader.onLoadFinished(TechFragment.java:192)
at com.ire.blogbot.fragments.TechFragment$NewsDataLoader.onLoadFinished(TechFragment.java:131)
at android.support.v4.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:476)
at android.support.v4.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:444)
at android.support.v4.content.Loader.deliverResult(Loader.java:126)
at com.ire.blogbot.fragments.TechFragment$NewsDataLoader$1.deliverResult(TechFragment.java:164)
at com.ire.blogbot.fragments.TechFragment$NewsDataLoader$1.deliverResult(TechFragment.java:137)
at android.support.v4.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:252)
at android.support.v4.content.AsyncTaskLoader$LoadTask.onPostExecute(AsyncTaskLoader.java:80)
at android.support.v4.content.ModernAsyncTask.finish(ModernAsyncTask.java:485)
at android.support.v4.content.ModernAsyncTask$InternalHandler.handleMessage(ModernAsyncTask.java:502)
at android.os.Handler.dispatchMessage(Handler.java:102)
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)
消息對象可能是空的,mNewsAdapter沒有初始化,所以你不能叫setOnItemClickListener在空對象上。 – Alex
當新聞對象不爲null時,您正在初始化mNewsAdapter,那麼爲什麼不移動setOnItemClickListener部分,如果您對新聞對象執行空檢查的條件相同。 – SAJ
謝謝。這阻止了事故的發生。但我注意到,點擊操作現在不起作用。 – Ire