0

我想打開一個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) 
+0

消息對象可能是空的,mNewsAdapter沒有初始化,所以你不能叫setOnItemClickListener在空對象上。 – Alex

+0

當新聞對象不爲null時,您正在初始化mNewsAdapter,那麼爲什麼不移動setOnItemClickListener部分,如果您對新聞對象執行空檢查的條件相同。 – SAJ

+0

謝謝。這阻止了事故的發生。但我注意到,點擊操作現在不起作用。 – Ire

回答

0

移動

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); 
       } 
      } 
     }); 

mNewsAdapter = new NewsAdapter(news); 
+0

謝謝。這工作,但點擊操作不起作用 – Ire

1

試試這個代碼,它是工作

recyclerView.addOnItemTouchListener(
      new RecyclerItemClickListener(getActivity(), new RecyclerItemClickListener.OnItemClickListener() { 
       @Override public void onItemClick(View view, int position) { 

        // on click 
       } 
      }) 
    ); 

RecyclerItemClickListener類

public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener { 

private OnItemClickListener mListener; 

public interface OnItemClickListener { 
    public void onItemClick(View view, int position); 
} 

GestureDetector mGestureDetector; 

public RecyclerItemClickListener(Context context, OnItemClickListener listener) { 
    mListener = listener; 
    mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { 
     @Override 
     public boolean onSingleTapUp(MotionEvent e) { 
      return true; 
     } 
    }); 
} 

@Override 
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) { 
    View childView = view.findChildViewUnder(e.getX(), e.getY()); 
    if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) { 
     mListener.onItemClick(childView, view.getChildAdapterPosition(childView)); 
    } 
    return false; 
} 

@Override 
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { 
} 

@Override 
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { 

}} 
+0

謝謝。這完全工作 – Ire

相關問題