2017-05-16 3 views
-8

私はリストを持っています。リストの各項目にcardviewカードを設定しました。スワイプで削除を実装しましたが、最後の項目(最後のカード)を削除するとIndexOutOfBoundsExceptionがスローされます。 マイコード:私は次のような問題に取り組むために道が必要です。

活動:

public class FirstPage extends Activity 
{ 
    RallyRestApi restApi; 
    private RecyclerView recyclerView; 
    private CustomAdapter adapter; 
    private List<MyData> data_list; 
    private Context mcontext; 
    String username; 
    String password; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     setContentView(R.layout.activity_first_page); 
     mcontext=this; 
     recyclerView = (RecyclerView) findViewById(R.id.recycler_view); 
     data_list = new ArrayList<>(); 
     load_data(); 
     recyclerView.setLayoutManager(new LinearLayoutManager(mcontext,LinearLayoutManager.HORIZONTAL,false)); 
     adapter = new CustomAdapter(FirstPage.this,data_list); 
     recyclerView.setAdapter(adapter); 
     username=getIntent().getStringExtra("username"); 
     password=getIntent().getStringExtra("password"); 
     ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.UP) 
     { 
      @Override 
      public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) 
      { 
       Toast.makeText(getApplicationContext(), "on Move", Toast.LENGTH_SHORT).show(); 
       return false; 
      } 

      @Override 
      public void onSwiped(final RecyclerView.ViewHolder viewHolder, int swipeDir) 
      { 

       Toast.makeText(getApplicationContext(), "Task Status changed to COMPLETE", Toast.LENGTH_LONG).show(); 
       String username = getIntent().getStringExtra("username"); 
       String password = getIntent().getStringExtra("password"); 
       try 
       { 
        restApi=new RallyRestApi(new URI("https://rally1.rallydev.com"),username,password); 
        JsonObject updatedValues = new JsonObject(); 
        updatedValues.addProperty("State", "Completed"); 
        UpdateRequest taskUpdate = new UpdateRequest(data_list.get(viewHolder.getAdapterPosition()).getRef(), updatedValues); 
        restApi.update(taskUpdate); 
        data_list.remove(viewHolder.getAdapterPosition()); 
        adapter.notifyDataSetChanged(); 
       } 
       catch (URISyntaxException | IOException e) 
       { 
          e.printStackTrace(); 
       } 
      } 
     }; 
     ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback); 
     itemTouchHelper.attachToRecyclerView(recyclerView); 
    } 

私のアダプタクラス:

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> { 

    private Context context; 
    private List<MyData> my_data; 
    FirstPage activity; 
    RallyRestApi restApi; 

    public CustomAdapter(FirstPage activity, List<MyData> my_data) 
    { 

     this.my_data = my_data; 
     this.activity=activity; 

    } 
    @Override 
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) 
    { 
     View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.card,parent,false); 
     itemView.setMinimumWidth(parent.getMeasuredWidth()); 
     itemView.setMinimumHeight(parent.getMeasuredHeightAndState()); 
     return new ViewHolder(itemView); 
    } 

    @Override 
    public void onBindViewHolder(final ViewHolder holder, final int position) 
    { 
     holder.userstory.setText("User Story: "+my_data.get(position).getUserstory()); 
     holder.tasks.setText("Task: "+my_data.get(position).getTask()); 
     holder.seekBar.setMax(my_data.get(position).getEstimate()); 
     holder.seekBar.setProgress(my_data.get(position).getActual()); 
     holder.actual_estimate.setText(my_data.get(position).getActual()+"/"+my_data.get(position).getEstimate()); 
     holder.seekBar.setOnSeekBarChangeListener(new CircularSeekBar.OnCircularSeekBarChangeListener() { 
      @Override 
      public void onProgressChanged(CircularSeekBar circularSeekBar, int progress, boolean fromUser) 
      { 
//IOB exception 
       holder.seekBar.setProgress(holder.seekBar.getProgress()); 
       holder.actual_estimate.setText(holder.seekBar.getProgress()+"/"+my_data.get(position).getEstimate()); 
      } 

      @Override 
      public void onStopTrackingTouch(CircularSeekBar seekBar) 
      { 
       try 
       { 
        restApi=new RallyRestApi(new URI("https://rally1.rallydev.com"),activity.username,activity.password); 
        JsonObject updatedValues = new JsonObject(); 
        updatedValues.addProperty("Actuals", holder.seekBar.getProgress()); 
        UpdateRequest taskUpdate = new UpdateRequest(my_data.get(position).getRef(), updatedValues); 
        restApi.update(taskUpdate); 
        holder.actual_estimate.setText(holder.seekBar.getProgress()+"/"+my_data.get(position).getEstimate()); 
        holder.seekBar.setProgress(holder.seekBar.getProgress()); 
       } 
       catch (URISyntaxException | IOException e) 
       { 
        e.printStackTrace(); 
       } 
      } 
      @Override 
      public void onStartTrackingTouch(CircularSeekBar seekBar) 
      { 

      } 
     }); 
     holder.seekBar.setProgress(holder.seekBar.getProgress()); 
     holder.actual_estimate.setText(holder.seekBar.getProgress()+"/"+my_data.get(position).getEstimate()); 
    } 

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

    public class ViewHolder extends RecyclerView.ViewHolder 
    { 
     public TextView userstory,tasks,actual_estimate; 
     public CircularSeekBar seekBar; 
// 
     public ViewHolder(View itemView) 
     { 
      super(itemView); 
      userstory=(TextView) itemView.findViewById(R.id.tvUserStory); 
      tasks=(TextView) itemView.findViewById(R.id.tvTask); 
      seekBar=(CircularSeekBar) itemView.findViewById(R.id.circularSeekBar1); 
      actual_estimate=(TextView) itemView.findViewById(R.id.tvactuals_estimate); 
     } 
    } 
} 

のErrorLog:

java.lang.IndexOutOfBoundsException:無効なインデックス2、サイズは2 です でjava.util.ArrayList.throwIndexOutOfB で com.bmc.apetkar.akshay_rallyrest.CustomAdapter $ 1.onProgressChanged(CustomAdapter.java:68) でjava.util.ArrayList.get(ArrayList.java:308) でoundsException(ArrayList.java:255) コム で com.bmc.apetkar.akshay_rallyrest.CustomAdapter $ 1.onProgressChanged(CustomAdapter.java:67) で.circularseekbar.CircularSeekBar.setProgress(CircularSeekBar.java:530) com.circularseekbar.CircularSeekBar.setProgress(CircularSeekBar.java: (CustomAdapter.java:61) でcom.bmc.apetkar.akshay_rallyrest.CustomAdapter.onBindViewHolder(CustomAdapter.java:32) android.support.v7.widget.RecyclerView $ Adapter.onBindViewHolder(RecyclerView.java:5277) で android.supportで.v7.widget.RecyclerView $ Adapter.bindViewHolder(RecyclerView.java:5310) でandroid.support.v7.widget.RecyclerView $ Recycler.getViewForPosition(RecyclerView.java:4568) android.support.v7.widgetで.RecyclerView $ Recycler.getViewForPosition(RecyclerView.java:4461) at android.support.v7.widget.L android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManagerでinearLayoutManager $ LayoutState.next(LinearLayoutManager.java:1962) でandroid.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1371) 。 Javaの:1334) android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:563) で android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2847で) アンドロイドで.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3145) at android.view.View .layout(View.java:16630) android.view.ViewGroup.layout(ViewGroup.java:5437) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743) at android.widget.LinearLayout.layoutVerticalアンドロイドでandroid.view.View.layout(View.java:16630) でandroid.widget.LinearLayout.onLayoutで(LinearLayout.java:1586) (LinearLayout.java:1495) 。view.ViewGroup.layout(ViewGroup.java:5437)android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)で android.widget.FrameLayout.onLayout(FrameLayout.java:273)で android.viewで 。 View.layout(View.java:16630) android.view.ViewGroup.layout(ViewGroup.java:5437) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743) android.widget.LinearLayoutにあります。 layoutVertical(LinearLayout.java:1586) android.widget.LinearLayout.onLayout(LinearLayout.java:1495) android.view.View.layout(View.java:16630) でandroid.widget.FrameLayout.onLayout(FrameLayout.java:273) でandroid.widget.FrameLayout.layoutChildren(FrameLayout.java:336) でandroid.view.ViewGroup.layout(ViewGroup.java:5437) でcom.android.internal.policy.PhoneWindow $ DecorView.onLayout(PhoneWindow.java:2678)android.view.View.layout(View.java:16630)の android.view.ViewGroup.layout(ViewGroup.java: 5437) android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2171) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1931) android.view.ViewRootImplアンドロイドで android.view.ViewRootImpl $ TraversalRunnable.run(ViewRootImpl.java:6013) でandroid.view.Choreographer $ CallbackRecord.run(Choreographer.java:858) で.doTraversal(ViewRootImpl.java:1107) .view.Choreographer.doCallbacks android.view.Choreographer.doFrameで(Choreographer.java:670) (Choreographer.java:606) でandroid.view.Choreographer $ FrameDisplayEventReceiver.run(Choreographer.java:844) でandroid.os.Handler.handleCallback(Handler.java:739) android.os.Handler.dispatchMessage(Handler.java:95)android.os.Looper.loopで でjava.lang.reflect.Method.invoke(ネイティブメソッド) でandroid.app.ActivityThread.mainで(Looper.java:148) (ActivityThread.java:5417) com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)で(ZygoteInit.java:726)

私はそれを知っているかもしれませんIndexOutOfBoundsExceptionの複製であるが、私はそれを参照し、リストが0から始まるので正確にどこをposition-1に変更する必要があるのか​​分からなかった。

+0

私はIndexOutOfBoundsExceptionを見つける必要がありますか? –

+0

エラーログを投稿しました – Akshay

+1

なぜ 'holder.seekBar.setProgress(holder.seekBar.getProgress());'。 'holder.seekBar.setProgress(progress);'という意味ですか?試してみてください –

答えて

3

例外は、あなたのonProgressChanged()リスナーにmy_data.get(position)に由来します。

このリスナーは、進行状況が変更されたときに非同期に呼び出されますが、onBindViewHolder()を実行すると元のpositionを参照します。

時刻XにonBindViewHolder()を実行すると、値2の位置が有効になります(リストに少なくとも3つのエントリがある場合)。リスナーはこの値2を保持し、それを保持します。

ここでアイテムを削除して2つのアイテムしか残っていない場合、position = 2は有効ではなくなりますが、リスナーはその値を保持していて、呼び出されると位置= 2のmy_dataにアクセスしようとします。今無効になります。

これを修正するには、リスナーを位置ではなく実際のデータに固定する必要があります。あなたはそうすることができます:

public void onBindViewHolder(final ViewHolder holder, final int position) 
{ 
    final SomeClass data = my_data.get(position); 

    holder.seekBar.setOnSeekBarChangeListener(new CircularSeekBar.OnCircularSeekBarChangeListener() { 
     @Override 
     public void onProgressChanged(CircularSeekBar circularSeekBar, int progress, boolean fromUser) 
     { 
      holder.seekBar.setProgress(holder.seekBar.getProgress()); 
      holder.actual_estimate.setText(holder.seekBar.getProgress()+"/" + data.getEstimate()); 
     } 
0

アイテムを削除する前に、リストが既に空であるかどうかを確認できます。

if(!data_list.isEmpty()){ 
    data_list.remove(viewHolder.getAdapterPosition()); 
    adapter.notifyDataSetChanged(); 
} 
関連する問題