0

我創建了具有卡片視圖,按鈕,文本視圖和開關的自定義列表。我已將標籤設置爲卡片視圖。獲取卡片視圖標籤時出現空指針異常

但是,當我試圖檢索表視圖持有人這個標籤它是拋出一個空指針異常。

如果我在一個監聽器中獲得標籤,它不會拋出任何異常。我不知道從哪裏訪問此標籤。

我想如果狀態是一個做setChecked真正的開關和setChecked應該是假的,如果狀態爲0

但我不明白在哪裏做呢?

CustomAlertAdapter

public class TableListAdapter extends RecyclerView.Adapter<TableListAdapter.TableViewHolder> { 


    public static TimeTableHelper db; 
    public static TimeTableList timeTableList; 

    public static int cardId,id,status=0; 
    public static boolean editMode; 
    public static List<TimeTable> tableList; 
    public static TimeTable t = new TimeTable(); 
    public static TimeTable ci; 

    public TableListAdapter(List<TimeTable> tableList,TimeTableList timeTableList) { 
     this.tableList = tableList; 
     this.timeTableList = timeTableList; 
    } 
    private Context context; 

    public TableListAdapter(Context context) { 
     this.context = context; 
    } 
    @Override 
    public int getItemCount() { 
      return tableList.size(); 
    } 

    @Override 
    public void onBindViewHolder(TableViewHolder tableViewHolder, int i) { 


     ci = tableList.get(i); 

     tableViewHolder.cv.setTag(i); 

     tableViewHolder.aSwitch.setTag(i); 

     Log.d("setId", String.valueOf(i)); 
     tableViewHolder.tableTitle.setText(ci.getTitle()); 

     ((GradientDrawable)tableViewHolder.color.getBackground()).setColor(ci.getTableColor()); 



    } 

    @Override 
    public TableViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 

     View itemView = LayoutInflater. 
        from(viewGroup.getContext()). 
        inflate(R.layout.table_card, viewGroup, false); 


     return new TableViewHolder(itemView); 
    } 

    public static class TableViewHolder extends RecyclerView.ViewHolder { 

     protected TextView tableTitle; 
     protected CardView cv; 
     protected SwitchCompat aSwitch; 
     protected Button color; 


     public TableViewHolder(final View v) { 
      super(v); 
      tableTitle = (TextView) v.findViewById(R.id.tableTitle); 
      cv = (CardView) v.findViewById(R.id.card_view); 
      aSwitch = (SwitchCompat) v.findViewById(R.id.switch2); 
      color = (Button) v.findViewById(R.id.selectColor); 

      db = new TimeTableHelper(timeTableList); 


      cv.setOnLongClickListener(new View.OnLongClickListener() { 

       @Override 
       public boolean onLongClick(final View v) { 
        // TODO Auto-generated method stub 

        final AlertDialog.Builder builder = new AlertDialog.Builder(timeTableList); 

        builder.setTitle("Delete Time Table") 
          .setMessage("Are you sure you want to Delete this Time Table?") 
          .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { 
           public void onClick(DialogInterface dialog, int which) { 

            cardId = (int)v.getTag(); 

            Log.d("cardId", String.valueOf(cardId)); 

            t = tableList.get(cardId); 
            id = t.getId(); 

            t = db.getTable(id); 
            db.deleteTable(t); 

            Intent intent = new Intent(timeTableList,TimeTableList.class); 
            timeTableList.finish(); 
            timeTableList.startActivity(intent); 

           } 

          }) 


          .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { 
           public void onClick(DialogInterface dialog, int which) { 
            // do nothing 
           } 
          }) 

          .setIcon(R.drawable.ic_warning_black_36dp) 
          .show(); 
        return true; 
       } 

      }); 


      cv.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(final View v) { 

        cardId = (int)v.getTag(); 

        Log.d("cardId", String.valueOf(cardId)); 

        t = tableList.get(cardId); 
        id = t.getId(); 

        Log.d("Id",String.valueOf(id)); 

        editMode = true; 
        Intent i = new Intent(timeTableList, NewTimeTable.class); 
        i.putExtra("editMode", editMode); 
        i.putExtra("tableId", id); 
        timeTableList.startActivity(i); 
       } 
      }); 


      cardId = (int) cv.getTag(); 

      Log.d("cardId", String.valueOf(cardId)); 

      t = tableList.get(cardId); 
      id = t.getId(); 

      if(status == 1) 
      { 
       aSwitch.setChecked(true); 
      } 
      else 
      { 
       aSwitch.setChecked(false); 
      } 


      aSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
       @Override 
       public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 



        if (isChecked) { 

         status = 1; 

         t = db.getTable(id); 
         t.setStatus(status); 
         db.updateStatus(t); 

         Log.d("status", String.valueOf(status)); 

         final List<TimeTable> events = db.getAllTables(); 
         for (TimeTable cn : events) { 
          String log = "Id: " + cn.getId() + " ,Title: " + cn.getTitle() + 
            "Status: " + cn.getStatus() + ",color: " + cn.getTableColor(); 
          Log.d("Data ", log); 
         } 

        } else { 

         status = 0; 

         t = db.getTable(id); 
         t.setStatus(status); 
         db.updateStatus(t); 
         final List<TimeTable> events = db.getAllTables(); 
         for (TimeTable cn : events) { 
          String log = "Id: " + cn.getId() + " ,Title: " + cn.getTitle() + 
            "Status: " + cn.getStatus() + ",color: " + cn.getTableColor(); 
          Log.d("Data ", log); 
         } 
         Log.d("status", String.valueOf(status)); 
        } 

       } 
      }); 

     } 
    } 

    public void updateAdapaterList(List<TimeTable> newTimeTableList) { 
     //Replace the current list with new list 
     this.tableList = newTimeTableList; 
     //notify the adapter that the data set has changed 
     notifyDataSetChanged(); 
    } 
} 

謝謝。

回答

1

您應該在視圖持有者中使用ID或標記以及任何類型的標識符,因爲您的視圖持有者可以在回收視圖中重複使用。我相信這是你造成麻煩的原因。

您應該使用onBindViewHolder來分配和鏈接每個視圖持有者的數據。

爲了分配這個方法裏面聽衆和ID,你應該做的事情如下所示:

public void onBindViewHolder(TableViewHolder tableViewHolder, int i) { 
    final TimeTable ci = tableList.get(i); 

    //... 

    tableViewHolder.setOnSomethingListener() { 
    // You can use the ci reference here because you declared it as final 
    // When this view is reused and references another position, the listener will be updated on the onBindViewHolder, to reference the new position that it will be being associated with 
    } 

} 

此外,在旁註,從這個類所有的靜態變量可能不應該是靜態的,因爲如果在其他視圖中碰巧有更多適配器實例,最終不希望它們互相干擾。

1

您應該將事物分配給適配器的onBindMethod中的ViewHolder中引用的UI字段,而不是ViewHolder

從你的代碼示例出:

public class TableListAdapter extends RecyclerView.Adapter<TableListAdapter.TableViewHolder> { 
    private Context context; 

    public TableListAdapter(Context context) { 
     this.context = context; 
    } 
    @Override 
    public int getItemCount() { 
     return tableList.size(); 
    } 

    @Override 
    public void onBindViewHolder(TableViewHolder tableViewHolder, int i) { 

    /* update referenced UI fields in view holder */ 

    tableViewHolder.cv.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(final View v) { 

       cardId = (int)v.getTag(); 

       Log.d("cardId", String.valueOf(cardId)); 

       t = tableList.get(cardId); 
       id = t.getId(); 

       Log.d("Id",String.valueOf(id)); 

       editMode = true; 
       Intent i = new Intent(timeTableList, NewTimeTable.class); 
       i.putExtra("editMode", editMode); 
       i.putExtra("tableId", id); 
       timeTableList.startActivity(i); 
      } 
     });  

     tableViewHolder.cv.setOnLongClickListener(new View.OnLongClickListener() { 

      @Override 
      public boolean onLongClick(final View v) { 
       // TODO Auto-generated method stub 

       final AlertDialog.Builder builder = new AlertDialog.Builder(timeTableList); 

       builder.setTitle("Delete Time Table") 
         .setMessage("Are you sure you want to Delete this Time Table?") 
         .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { 
          public void onClick(DialogInterface dialog, int which) { 

           cardId = (int)v.getTag(); 

           Log.d("cardId", String.valueOf(cardId)); 

           t = tableList.get(cardId); 
           id = t.getId(); 

           t = db.getTable(id); 
           db.deleteTable(t); 

           Intent intent = new Intent(timeTableList,TimeTableList.class); 
           timeTableList.finish(); 
           timeTableList.startActivity(intent); 

          } 

         }) 


         .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { 
          public void onClick(DialogInterface dialog, int which) { 
           // do nothing 
          } 
         }) 

         .setIcon(R.drawable.ic_warning_black_36dp) 
         .show(); 
       return true; 
      } 

     }); 
    } 

@Override 
public TableViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 

    /* Inflate view and pass it to view holder */ 
    View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.table_card, viewGroup, false); 

    return new TableViewHolder(itemView); 
} 

public static class TableViewHolder extends RecyclerView.ViewHolder { 

    protected TextView tableTitle; 
    protected CardView cv; 
    protected SwitchCompat aSwitch; 
    protected Button color; 


    public TableViewHolder(View v) { 
     super(v); 

     cv = (CardView) v.findViewById(R.id.card_view); // Reference your layout fields. 

    }  
} 

}