1

Привет, я новичок в Android и получаю проблемы с просмотром и фрагментом Recycler. Существует три фрагмента, которые можно прокручивать, и есть вид ресайклера с адаптером, который находится во фрагменте. Я получил пример кода от http://developer.android.com/training/implementing-navigation/lateral.html, но я получаю исключение null-указателя в объекте List. Заранее спасибо. Мой код показан ниже:Адаптер Android RecyclerView с исключением исключения нулевого указателя фрагмента

public class TripHistoryActivity extends FragmentActivity implements ActionBar.TabListener{ 
private static final String TAG = "TripHistoryActivity"; 
private CommonDBHelper commonDBHelper; 

private List<Trip> allTrips; 
private ArrayList<Trip> currentTrips; 
private ArrayList<Trip> pastTrips; 
private ArrayList<Trip> futureTrips; 

AppSectionsPagerAdapter mAppSectionsPagerAdapter; 

ViewPager mViewPager; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_trip_history); 
    commonDBHelper = new CommonDBHelper(this); 
    TripDBHelper tripDBHelper = new TripDBHelper(commonDBHelper.getWritableDatabase()); 

    allTrips = tripDBHelper.getAllTrips(); 
    currentTrips = new ArrayList<>(); 
    pastTrips = new ArrayList<>(); 
    futureTrips = new ArrayList<>(); 
    Calendar calendar = Calendar.getInstance(); 
    int currentDay = calendar.get(calendar.DAY_OF_MONTH); 
    int currentMonth = calendar.get(calendar.MONTH); 
    int currentYear = calendar.get(calendar.YEAR); 
    for (Trip trip : allTrips) { 

     String date = trip.getTime().substring(0, trip.getTime().indexOf(" ")); 
     String[] dates = date.split("/"); 
     if (currentYear < Integer.valueOf(dates[2])) { 
      futureTrips.add(trip); 
     } 
     else if (currentYear > Integer.valueOf(dates[2]) 
       || currentMonth > Integer.valueOf(dates[0]) 
       || currentDay > Integer.valueOf(dates[1])) { 
      pastTrips.add(trip); 
     } 
     else { 
      currentTrips.add(trip); 
     } 
    } 

    mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getSupportFragmentManager()); 
    final ActionBar actionBar = getActionBar(); 
    actionBar.setHomeButtonEnabled(false); 
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 

    mViewPager = (ViewPager) findViewById(R.id.pager); 
    mViewPager.setAdapter(mAppSectionsPagerAdapter); 
    mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { 
     @Override 
     public void onPageSelected(int position) { 
      // When swiping between different app sections, select the corresponding tab. 
      // We can also use ActionBar.Tab#select() to do this if we have a reference to the 
      // Tab. 
      actionBar.setSelectedNavigationItem(position); 
     } 
    }); 

    for (int i = 0; i < mAppSectionsPagerAdapter.getCount(); i++) { 
     // Create a tab with text corresponding to the page title defined by the adapter. 
     // Also specify this Activity object, which implements the TabListener interface, as the 
     // listener for when this tab is selected. 
     actionBar.addTab(
       actionBar.newTab() 
         .setText(mAppSectionsPagerAdapter.getPageTitle(i)) 
         .setTabListener(this)); 
    } 
} 


@Override 
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { 
} 

@Override 
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { 
    // When the given tab is selected, switch to the corresponding page in the ViewPager. 
    mViewPager.setCurrentItem(tab.getPosition()); 
} 

@Override 
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { 
} 

/** 
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to one of the primary 
* sections of the app. 
*/ 
public class AppSectionsPagerAdapter extends FragmentPagerAdapter { 

    public AppSectionsPagerAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public android.support.v4.app.Fragment getItem(int i) { 
     switch (i) { 
      case 0: 
       android.support.v4.app.Fragment currentTripsFragment = new CurrentTripsFragment(); 
       Bundle currentTripsBundle = new Bundle(); 
       currentTripsBundle.putParcelableArrayList("currentTrips", currentTrips); 
       currentTripsFragment.setArguments(currentTripsBundle); 
       return currentTripsFragment; 

      case 1: 
       android.support.v4.app.Fragment pastTripsFragment = new PastTripsFragment(); 
       Bundle pastTripsBundle = new Bundle(); 
       pastTripsBundle.putParcelableArrayList("pastTrips", pastTrips); 
       pastTripsFragment.setArguments(pastTripsBundle); 
       return pastTripsFragment; 

      default: 
       android.support.v4.app.Fragment futureTripsFragment = new FutureTripsFragment(); 
       Bundle futureTripsBundle = new Bundle(); 
       futureTripsBundle.putParcelableArrayList("futureTrips", futureTrips); 
       futureTripsFragment.setArguments(futureTripsBundle); 
       return futureTripsFragment; 
     } 
    } 

    @Override 
    public int getCount() { 
     return 3; 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     switch (position) { 
      case 0: 
       return "Current Trips"; 
      case 1: 
       return "Past Trips"; 
      case 2: 
       return "Future Trips"; 
      default: 
       return "Fault"; 
     } 
    } 
} 

/** 
* A fragment that launches other parts of the demo application. 
*/ 
public static class CurrentTripsFragment extends android.support.v4.app.Fragment { 
    private RecyclerView mRecyclerView; 
    private Context context; 
    List<Trip> currentTrips; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View rootView = inflater.inflate(R.layout.fragment_current_trips, container, false); 
     context = rootView.getContext(); 
     mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view); 

     currentTrips = getArguments().getParcelableArrayList("currentTrips"); 
     Log.d(TripHistoryActivity.TAG, String.valueOf(currentTrips == null)); 

     RecyclerView.LayoutManager manager = new LinearLayoutManager(context); 
     mRecyclerView.setLayoutManager(manager); 
     mRecyclerView.setItemAnimator(new DefaultItemAnimator()); 
     CardViewAdapter cardViewAdapter = new CardViewAdapter(currentTrips); 
     mRecyclerView.setAdapter(cardViewAdapter); 
     cardViewAdapter.setOnItemClick(new CardViewAdapter.OnItemClick() { 
      @Override 
      public void onItemClick(int position) { 
       handleItemClick(position); 
      } 
     }); 

     return rootView; 
    } 

    public void handleItemClick (int position) { 
     Toast.makeText(context, "Clicked " + position, Toast.LENGTH_SHORT).show(); 
     Intent intent = new Intent(context, ViewTripActivity.class); 
     intent.putExtra("trip", currentTrips.get(position)); 
     startActivity(intent); 
    } 
} 

Есть 2 других фрагмента, которые являются такими же, как этот, поэтому я их опускаю.

import android.support.v7.widget.RecyclerView; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.TextView; 

import com.nyu.cs9033.eta.R; 
import com.nyu.cs9033.eta.models.Trip; 

import java.util.List; 

/** 
* Created by Ray on 2016/4/2. 
*/ 
public class CardViewAdapter extends RecyclerView.Adapter<CardViewAdapter.CardViewHolder> { 
    private final List<Trip> trips; 

    public CardViewAdapter (List<Trip> trips) { 
     this.trips = trips; 
    } 

    public interface OnItemClick { 
     public void onItemClick(int position); 
    } 

    private OnItemClick onItemClick; 

    public void setOnItemClick (OnItemClick onItemClick) { 
     this.onItemClick = onItemClick; 
    } 

    @Override 
    public CardViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.history_list_item, parent, false); 
     return new CardViewHolder(view); 
    } 

    @Override 
    public void onBindViewHolder(final CardViewHolder holder, final int position) { 
     holder.name.setText(trips.get(position).getName()); 
     holder.location.setText(trips.get(position).getLocation()); 
     holder.time.setText(trips.get(position).getTime()); 
     if (onItemClick != null) { 
      holder.itemView.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        onItemClick.onItemClick(position); 
       } 
      }); 
     } 
    } 

    @Override 
    public int getItemCount() { 
     return trips.size(); 
    } 

    class CardViewHolder extends RecyclerView.ViewHolder { 
     private TextView name; 
     private TextView location; 
     private TextView time; 

     public CardViewHolder (View view) { 
      super(view); 
      name = (TextView) view.findViewById(R.id.card_trip_name); 
      location = (TextView) view.findViewById(R.id.card_trip_location); 
      time = (TextView) view.findViewById(R.id.card_trip_time); 
     } 
    } 

} 

Это то, что LogCat говорит:

FATAL EXCEPTION: mainProcess: com.nyu.cs9033.eta, PID: 14018 
java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' 
on a null object reference 
at com.nyu.cs9033.eta.adapters.CardViewAdapter.getItemCount(CardViewAdapter.java: 57) 
at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java: 2357) 
at android.view.View.measure(View.java: 18796) 
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java: 715) 
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java: 461) 
at android.view.View.measure(View.java: 18796) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java: 5951) 
at android.widget.FrameLayout.onMeasure(FrameLayout.java: 194) 
at android.view.View.measure(View.java: 18796) 
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java: 1488) 
at android.view.View.measure(View.java: 18796) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java: 5951) 
at android.widget.FrameLayout.onMeasure(FrameLayout.java: 194) 
at android.view.View.measure(View.java: 18796) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java: 5951) 
at com.android.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java: 446) 
at android.view.View.measure(View.java: 18796) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java: 5951) 
at android.widget.FrameLayout.onMeasure(FrameLayout.java: 194) 
at com.android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.java: 2643) 
at android.view.View.measure(View.java: 18796) 
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java: 2108) 
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java: 1224) 
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java: 1460) 
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java: 1115) 
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java: 6023) 
at android.view.Choreographer$CallbackRecord.run(Choreographer.java: 858) 
at android.view.Choreographer.doCallbacks(Choreographer.java: 670) 
at android.view.Choreographer.doFrame(Choreographer.java: 606) 
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java: 844) 
at android.os.Handler.handleCallback(Handler.java: 739) 
at android.os.Handler.dispatchMessage(Handler.java: 95) 
at android.os.Looper.loop(Looper.java: 148) 
at android.app.ActivityThread.main(ActivityThread.java: 5422) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java: 726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java: 616) 
+0

Это исключения нулевого указателя и как-то это ясно показывает, что 'Список trips' не инициализирован. Почему вы все равно объявляете список окончательным? Не ставить его в качестве ответа, поскольку я пока не уверен в реальной проблеме. В любом случае, вы можете взглянуть еще раз и сообщить мне, если проблема не в том, о чем я упоминал. –

+0

@Reaz Murshed Да, я знаю, это потому, что поездки не инициализированы. Причина добавления final - это просто привычка Java, так как мой преподаватель курса Java сказал, что все переменные, которые могут быть финализированы, должны быть добавлены к окончательному ключевому слову. Чинтан Сони отметил, что список должен быть инициализирован методом onCreate(), и это помогло отлично. В любом случае, спасибо за ваш комментарий. –

ответ

1

Вы должны получить комплект от onCreate() вместо onCreateView(). Попробуйте ниже изменения в классе Фрагмент:

public static class CurrentTripsFragment extends android.support.v4.app.Fragment { 

private RecyclerView mRecyclerView; 
private Context context; 
List<Trip> currentTrips; 

@Override 
public void onCreate(Bundle savedInstanceState){ 
    super().onCreate(savedInstanceState); 

    if(getArguments()!= null){ 
     currentTrips = getArguments().getParcelableArrayList("currentTrips"); 
    } 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    View rootView = inflater.inflate(R.layout.fragment_current_trips, container, false); 
    context = rootView.getContext(); 
    mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view); 

    Log.d(TripHistoryActivity.TAG, String.valueOf(currentTrips == null)); 

    RecyclerView.LayoutManager manager = new LinearLayoutManager(context); 
    mRecyclerView.setLayoutManager(manager); 
    mRecyclerView.setItemAnimator(new DefaultItemAnimator()); 
    CardViewAdapter cardViewAdapter = new CardViewAdapter(currentTrips); 
    mRecyclerView.setAdapter(cardViewAdapter); 
    cardViewAdapter.setOnItemClick(new CardViewAdapter.OnItemClick() { 
     @Override 
     public void onItemClick(int position) { 
      handleItemClick(position); 
     } 
    }); 

    return rootView; 
} 

public void handleItemClick (int position) { 
    Toast.makeText(context, "Clicked " + position, Toast.LENGTH_SHORT).show(); 
    Intent intent = new Intent(context, ViewTripActivity.class); 
    intent.putExtra("trip", currentTrips.get(position)); 
    startActivity(intent); 
} 
} 
+0

Действительно благодарю вас! Это помогает мне прекрасно и экономит мой день! Спасибо! –

0

Вы получаете исключения нулевого указателя в вашем списке, который вы используете, чтобы показать элементы списка в поле зрения ресайклера ... Пожалуйста, проверьте, что вы получаете ваши данные в списке или нет ... проблема, кажется, здесь:

CardViewAdapter cardViewAdapter = new CardViewAdapter(currentTrips); 

и здесь:

currentTrips = getArguments().getParcelableArrayList("currentTrips"); 
+0

Да, я знаю, что что-то не так с передачей данных в список, но я не знал почему. Но Chintan Soni отлично решил это, инициировав объект списка в методе onCreate(), а не в onCreateView(). Но спасибо за ваш комментарий! –

Смежные вопросы