2016-05-27 2 views
1

это мой код:почему findviewbyposition() из recyclerView возвращает нуль только иногда

public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) 
{ 

    View rootView = inflater.inflate(R.layout.fragment_add_aircraft, container, false); 

    recyclerView=(RecyclerView)rootView.findViewById(R.id.recyclerAircraftAdd); 
    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity()); 
    recyclerView.setLayoutManager(layoutManager); 
    adapter = new AircraftAdapter(getActivity(),path); 
    recyclerView.setAdapter(adapter); 
    Button button = (Button)rootView.findViewById(R.id.salvaereo); 

    button.setOnClickListener(new View.OnClickListener() 
    { 
     @Override 
     public void onClick(View v) 
     { 
      adapter = (AircraftAdapter)recyclerView.getAdapter(); 
      ParseObject aircraft = new ParseObject("Aircrafts"); 

      for(int i = 0;i<adapter.getItemCount(); i++) 
      { 
      if (i== 0) //first card 
      { 
       View view = recyclerView.getLayoutManager().findViewByPosition(i); 
       ImageView image = (ImageView)view.findViewById(R.id.aircfraftImg); 
       image.setDrawingCacheEnabled(true); 
       image.buildDrawingCache(); 
       Bitmap bm = image.getDrawingCache(); 
       ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
       bm.compress(Bitmap.CompressFormat.PNG, 100, stream); 
       byte[] bytes = stream.toByteArray(); 
       ParseFile file = new ParseFile("Image.jpg",bytes); 
       aircraft.put("aircraft_image",file); 

       file.saveInBackground(new SaveCallback() { 
        @Override 
        public void done(ParseException e) { 
         Log.d("sa","tutto ok"); 
        } 
       }); 

      } 
      else if (i ==1) //second card 
      { 
       View view = recyclerView.getLayoutManager().findViewByPosition(i); 
       EditText immatricolazione =(EditText)view.findViewById(R.id.immatricolazione); 
       EditText modello = (EditText)view.findViewById(R.id.modello); 
       EditText manifacturer = (EditText)view.findViewById(R.id.manifacturer); 
       EditText categoria = (EditText)view.findViewById(R.id.categoria); 
       EditText classe = (EditText)view.findViewById(R.id.classe); 
       EditText velocita = (EditText)view.findViewById(R.id.velocita); 
       EditText autonomia = (EditText)view.findViewById(R.id.autonomia); 
       EditText consumo = (EditText)view.findViewById(R.id.consumo); 
       EditText posti = (EditText)view.findViewById(R.id.postitotali); 
       EditText costo = (EditText)view.findViewById(R.id.costorario); 

       aircraft.put("re",immatricolazione.getEditableText().toString()); 
       aircraft.put("ml",modello.getEditableText().toString()); 
       aircraft.put("man",manifacturer.getEditableText().toString()); 
       aircraft.put("Aircraft_Type",categoria.getEditableText().toString()); 
       aircraft.put("ar",classe.getEditableText().toString()); 
       aircraft.put("post",Integer.parseInt(posti.getEditableText().toString())); 
       aircraft.put("meter",Integer.parseInt(consumo.getEditableText().toString())); 
       aircraft.put("speed",Integer.parseInt(velocita.getEditableText().toString())); 
       aircraft.put("prezzi",Float.parseFloat(costo.getEditableText().toString())); 
       aircraft.put("fuel",Integer.parseInt(autonomia.getEditableText().toString())); 
      } 
      else if(i==2) //third card 
      { 
       View view = recyclerView.getLayoutManager().findViewByPosition(i); 
       EditText description = (EditText) view.findViewById(R.id.description); 
       aircraft.put("descrizione", description.getEditableText().toString()); 

       aircraft.put("User", ParseUser.getCurrentUser()); 

       dialog = ProgressDialog.show(getActivity(), "", "Caricamento aereo in corso...", true); 

       aircraft.saveInBackground(new SaveCallback() { 

        public void done(ParseException e) { 
         dialog.dismiss(); 

         if (e == null) { 
          new AlertDialog.Builder(getActivity()) 
            .setMessage("Caricamento aereo avvenuto con successo!") 
            .setCancelable(false) 
            .setPositiveButton("Ok", new DialogInterface.OnClickListener() { 
             @Override 
             public void onClick(DialogInterface dialog, int which) { 

             } 
            }).create().show(); 
         } else { 
          new AlertDialog.Builder(getActivity()) 
            .setMessage("Non è stato possibile caricare l'aereo, riprova più tardi!") 
            .setCancelable(false) 
            .setPositiveButton("Ok", new DialogInterface.OnClickListener() { 
             @Override 
             public void onClick(DialogInterface dialog, int which) { 

             } 
            }).create().show(); 
         } 


        } 
       }); 
      } 
      } 

     } 
    }); 

    return rootView; 
} 

но есть такая проблема: если я заряжаю фото (первая карту) и нажмите кнопку, он загружает фотографию, но если я пишу в EditText, он выходит из строя и дает мне эту ошибку:

Process: com.run.flyproject, PID: 10796 java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference at com.run.flyproject.Fragments.AddAircraftFragment$1.onClick(AddAircraftFragment.java:78) at android.view.View.performClick(View.java:4756) at android.view.View$PerformClick.run(View.java:19749) 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:5253) 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:899) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

+0

Сумма просмотров и количество предметов различны. RecyclerView только создает столько просмотров, сколько необходимо для заполнения его размера. Возвращаемое значение null означает, что представление не существует для этой позиции позиции. – DeeV

+0

, но у меня есть только 3 вида. – ste9206

+0

«null, если позиция не выложена». В любом случае вид не существует, и вам нужно подготовиться к нему. https://developer.android.com/reference/android/support/v7/widget/RecyclerView.LayoutManager.html#findViewByPosition(int) – DeeV

ответ

2

Не то, чтобы это явный ответ (явный ответ был бы примерно как «Количество ваших адаптеров не совпадает с представлениями, доступными от вашего адаптера»), но мои комментарии были, вероятно, немного запутавшись. Вы могли бы сделать что-то вроде этого ...

public class YourAdapter extends RecyclerView.Adapter<YourViewHolder>{ 

    private boolean mSaveImages = false; 
    private SparseArray<Boolean> mImageSavedFlags = new SparseArray<>(); 

    public void toggleSaveStatus(){ 
     mSaveImages = !mSaveImages; 
    } 

    // ... your code 

    @Override 
    public void onBindViewHolder(YourViewHolder holder, final int position) { 
     // Could also manage this in a loop or something 
     // in your constructor/when you set your adapter data 
     // but this will set our SparseArray 
     if(mImageSavedFlags.get(position) == null) 
      mImageSavedFlags.put(position, false); 

     // ... your code 
     if(mSaveImages && !mImageSavedFlags.get(position){ 
      // ... save your image 
      mImageSavedFlags.put(position, true); 
     } 
    } 

    // ... your code 
} 

Этого пути, когда вы пытаетесь связать вид, вы можете проверить, если вы хотите, чтобы сохранить источник ImageViews, и если вы еще не сохранили его, если вы еще 't он сохранит источник и обновит SparseArray.

Для переключения состояния просто сделать что-то вроде этого

button.setOnClickListener(new View.OnClickListener() 
{ 
    @Override 
    public void onClick(View v){ 
     adapter.toggleSaveStatus(); 
    } 
} 

Стоит отметить, что это будет только сохранить изображения, которые вы на самом деле прокрутки в после вы переключаетесь сохранения настройки на. Я полагаю, вы могли бы заставить прокручивать вас RecyclerView, но это проникает во что-то другое.

Также важно понимать, что если вы делаете что-то вроде загрузки изображений с URL-адреса или из ваших чертежей на основе позиции или чего-то еще, вам не нужен ваш ImageView для загрузки источника, прежде чем вы сможете его сохранить, существует множество способов (включая библиотеки) для сохранения изображений, которые еще не были явно загружены в ваше приложение, что полностью устранит необходимость включения вашего адаптера в процесс.

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

+0

Благодарим вас за помощь! – ste9206

0

вы получаете NullPointerException как ваши recyclerView.getLayoutManager().find... возвращается null и ваш второй вопрос, почему вы не получите вид на позицию, проверить recyclerView.getLayoutManager().getChildCount() проверить т у вас есть какой-либо ребенок для этого индекса

0

Вы можете использовать использовать оба

recyclerViewInstance.findViewHolderForAdapterPosition (adapterPosition) и recyclerViewInstance.findViewHolderForLayoutPosition (layoutPosition). Убедитесь, что вид RecyclerView использует два типа позиций

Позиция адаптера: положение элемента в адаптере. Это позиция с точки зрения адаптера. Позиция макета: позиция элемента в последнем расчете макета. Это позиция с точки зрения LayoutManager. Вы должны использовать getAdapterPosition() для findViewHolderForAdapterPosition (adpterPosition) и getLayoutPosition() для findViewHolderForLayoutPosition (layoutPosition).

Возьмите переменную-член, чтобы удерживать ранее выбранную позицию позиции в адаптере recyclerview и другую переменную-член, чтобы проверить, щелкнет ли пользователь в первый раз или нет.

Образец кода и снимки экрана прилагаются для получения дополнительной информации внизу.

public class MainActivity extends AppCompatActivity {  

private RecyclerView mRecyclerList = null;  
private RecyclerAdapter adapter = null;  

@Override  
protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
    setContentView(R.layout.activity_main);  

    mRecyclerList = (RecyclerView) findViewById(R.id.recyclerList);  
}  

@Override  
protected void onStart() {  
    RecyclerView.LayoutManager layoutManager = null;  
    String[] daysArray = new String[15];  
    String[] datesArray = new String[15];  

    super.onStart();  
    for (int i = 0; i < daysArray.length; i++){  
     daysArray[i] = "Sunday";  
     datesArray[i] = "12 Feb 2017";  
    }  

    adapter = new RecyclerAdapter(mRecyclerList, daysArray, datesArray);  
    layoutManager = new LinearLayoutManager(MainActivity.this);  
    mRecyclerList.setAdapter(adapter);  
    mRecyclerList.setLayoutManager(layoutManager);  
}  
}  


public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyCardViewHolder>{   

private final String TAG = "RecyclerAdapter";   
private Context mContext = null;   
private TextView mDaysTxt = null, mDateTxt = null;  
private LinearLayout mDateContainerLayout = null;  
private String[] daysArray = null, datesArray = null;  
private RecyclerView mRecyclerList = null;  
private int previousPosition = 0;  
private boolean flagFirstItemSelected = false;  

public RecyclerAdapter(RecyclerView mRecyclerList, String[] daysArray, String[] datesArray){  
    this.mRecyclerList = mRecyclerList;  
    this.daysArray = daysArray;  
    this.datesArray = datesArray;  
}  

@Override  
public MyCardViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
    LayoutInflater layoutInflater = null;  
    View view = null;  
    MyCardViewHolder cardViewHolder = null;  
    mContext = parent.getContext();  
    layoutInflater = LayoutInflater.from(mContext);  
    view = layoutInflater.inflate(R.layout.date_card_row, parent, false);  
    cardViewHolder = new MyCardViewHolder(view);  
    return cardViewHolder;  
}  

@Override  
public void onBindViewHolder(MyCardViewHolder holder, final int position) {  
    mDaysTxt = holder.mDaysTxt;  
    mDateTxt = holder.mDateTxt;  
    mDateContainerLayout = holder.mDateContainerLayout;  

    mDaysTxt.setText(daysArray[position]);  
    mDateTxt.setText(datesArray[position]);  

    if (!flagFirstItemSelected){  
     mDateContainerLayout.setBackgroundColor(Color.GREEN);  
     flagFirstItemSelected = true;  
    }else {  
     mDateContainerLayout.setBackground(null);  
    }  
}  

@Override  
public int getItemCount() {  
    return daysArray.length;  
}  

class MyCardViewHolder extends RecyclerView.ViewHolder{  
    TextView mDaysTxt = null, mDateTxt = null;  
    LinearLayout mDateContainerLayout = null;  
    LinearLayout linearLayout = null;  
    View view = null;  
    MyCardViewHolder myCardViewHolder = null;  

    public MyCardViewHolder(View itemView) {  
     super(itemView);  
     mDaysTxt = (TextView) itemView.findViewById(R.id.daysTxt);  
     mDateTxt = (TextView) itemView.findViewById(R.id.dateTxt);  
     mDateContainerLayout = (LinearLayout) itemView.findViewById(R.id.dateContainerLayout);  

     mDateContainerLayout.setOnClickListener(new View.OnClickListener() {  
      @Override  
      public void onClick(View v) {  
       LinearLayout linearLayout = null;  
       View view = null;  

       if (getAdapterPosition() == previousPosition){  
        view = mRecyclerList.findViewHolderForAdapterPosition(previousPosition).itemView;  
        linearLayout = (LinearLayout) view.findViewById(R.id.dateContainerLayout);  
        linearLayout.setBackgroundColor(Color.GREEN);  
        previousPosition = getAdapterPosition();  

       }else {  
        view = mRecyclerList.findViewHolderForAdapterPosition(previousPosition).itemView;  
        linearLayout = (LinearLayout) view.findViewById(R.id.dateContainerLayout);  
        linearLayout.setBackground(null);  

        view = mRecyclerList.findViewHolderForAdapterPosition(getAdapterPosition()).itemView;  
        linearLayout = (LinearLayout) view.findViewById(R.id.dateContainerLayout);  
        linearLayout.setBackgroundColor(Color.GREEN);  
        previousPosition = getAdapterPosition();  
       }  
      }  
     });  
    }  
}  

} источник

screen shot 1scrren shot 2