2014-01-09 4 views
1

У меня есть активность, которая отображает пользовательские сообщения из БД в ListView. ListView показывает различную информацию о сообщении правильно, и каждая строка в listView имеет onClickListener, который запускает другое действие, чтобы показать дополнительную информацию о сообщении.Андроид Курсор в представлении должен быть окончательным?

Все это прекрасно работает. Я добавил CheckBox в список. CheckBox проверяется, чтобы отметить, что для удаления было выбрано сообщение. Каждое сообщение имеет уникальный идентификатор guid, который хранится в БД, поэтому он доступен через курсор и адаптер в представлении. Когда щелкнет строка, этот ключ передается через onclicklistener в следующее действие.

Все это прекрасно работает. Теперь я добавил обработчик onCheckedChanged. Когда я устанавливаю флажок, я хочу получить этот уникальный идентификатор guid от курсора в getView.

Если флажок установлен в oneneredChanged, он использует анонимный внутренний класс, поэтому курсор не является окончательным.

К сожалению, это означает, что в БД есть 5 сообщений, и я проверяю все, что нужно удалить, тогда все они имеют один и тот же указатель, потому что после того, как оно установлено на первое значение, оно не может быть изменено (окончательное).

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

link

Как я могу решить эту проблему? В основном, как я могу сделать данные в курсоре доступными внутри метода onCheckedChanged, не делая курсор окончательным?

Заранее спасибо

public class ViewMessagesActivity extends Activity{ 

    private static final String TAG = ViewMessagesActivity.class.getSimpleName(); 
    final String    BACKPRESS_ACTION = "com.carefreegroup.rr3.BACKPRESS_ACTION"; 

    NfcScannerApplication nfcscannerapplication; 
    Cursor cursorMessages; 
    ListView listView; 
    SimpleCursorAdapter adapter; 
    MyAdapter myAdapter; 
    TextView noMessages; 


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

     setContentView(R.layout.viewmessages); 

     nfcscannerapplication = (NfcScannerApplication) getApplication(); 





      //transactionCount = (TextView)findViewById(R.id.textviewtransactionsfordaycount); 
      listView = (ListView) findViewById(R.id.listviewmessages); 

      noMessages = (TextView)findViewById(R.id.textviewnomessageslabel); 

      // get data 
      cursorMessages = nfcscannerapplication.loginValidate.queryAllFromMessage(); 
      cursorMessages.moveToLast(); 
      startManagingCursor(cursorMessages); 

      // setup adapter and show the data 





      if(cursorMessages.getCount() == 0){ 


       noMessages.setVisibility(View.VISIBLE); 
       listView.setVisibility(View.GONE); 

      }else{ 

       listView.setVisibility(View.VISIBLE); 
       noMessages.setVisibility(View.GONE); 

      } 




      String[] from = { 
        LoginValidate.C_MESSAGE_CREATED_AT, LoginValidate.C_MESSAGE_TEXT, LoginValidate.C_MESSAGE_SENDER}; 
      int[] to = { R.id.messagecreatedat, R.id.messagetext, R.id.messagesender}; 

      myAdapter = new MyAdapter(nfcscannerapplication, R.layout.rowmessages, cursorMessages, from, to); 
      listView.setAdapter(myAdapter); 
      listView.setOnItemClickListener(myAdapter); 



    }//end of onCreate 







@Override 
    protected void onResume() { 
     super.onResume(); 


    } 




private class MyAdapter extends SimpleCursorAdapter implements OnItemClickListener { 

     public MyAdapter(Context context, int layout, Cursor c, String[] from, 
       int[] to) { 
      super(context, layout, c, from, to); 


     } 

     @Override 
     public 
     View getView(int position, View convertView, ViewGroup parent) { 
      Log.e(TAG, "inside myadapter getview for messages"); 
      View v = super.getView(position, convertView, parent); 
      if(v == null) 
       return null; 

      Cursor c = (Cursor)getItem(position); 

      v.setTag(c); 








      String messageSender = c.getString(c.getColumnIndex(LoginValidate.C_MESSAGE_SENDER)); 
      String isRepliedTo = c.getString(c.getColumnIndex(LoginValidate.C_MESSAGE_REPLIED)); 
      String isStandAlone = c.getString(c.getColumnIndex(LoginValidate.C_MESSAGE_IS_STANDALONE)); 




      ((TextView)v.findViewById(R.id.messagecreatedat)).setText(formattedMessCreatedAt); 
      ((TextView)v.findViewById(R.id.messagetext)).setText(messageText); 
      ((TextView)v.findViewById(R.id.messagesender)).setText(messageSender); 

      //#003F87 = blue 

      ((TextView)v.findViewById(R.id.messagecreatedat)).setTextColor(Color.parseColor("#003F87")); 
      ((TextView)v.findViewById(R.id.messagesender)).setTextColor(Color.parseColor("#003F87")); 
      ((TextView)v.findViewById(R.id.messagetext)).setTextColor(Color.parseColor("#FF0000")); 




      CheckBox cb = ((CheckBox)v.findViewById(R.id.list_checkbox)); 
      cb.setOnCheckedChangeListener(new OnCheckedChangeListener() { 

       @Override 
       public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 


        String messageGuid = c.getString(c.getColumnIndex(LoginValidate.C_MESSAGE_GUID)); 

        if(isChecked == true){ 

         Log.e(TAG, "checkBox true and guid = " + messageGuid); 
        }else{ 
         Log.e(TAG, "checkBox false and guid = " + messageGuid); 
        } 

       } 
      }); 


      return v; 
     } 

     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int pos, 
       long id) { 

      Cursor itemCursor = (Cursor) view.getTag(); 

      String messageGuid = itemCursor.getString(itemCursor.getColumnIndex(LoginValidate.C_MESSAGE_GUID)); 



      String messageText = itemCursor.getString(itemCursor.getColumnIndex(LoginValidate.C_MESSAGE_TEXT)); 
      String messageCreatedAt = itemCursor.getString(itemCursor.getColumnIndex(LoginValidate.C_MESSAGE_CREATED_AT)); 
      String messageSender = itemCursor.getString(itemCursor.getColumnIndex(LoginValidate.C_MESSAGE_SENDER)); 
      String messageReplied = itemCursor.getString(itemCursor.getColumnIndex(LoginValidate.C_MESSAGE_REPLIED)); 
      String messageSeen = itemCursor.getString(itemCursor.getColumnIndex(LoginValidate.C_MESSAGE_SEEN)); 
      String isStandAlone = itemCursor.getString(itemCursor.getColumnIndex(LoginValidate.C_MESSAGE_IS_STANDALONE)); 

      Intent i = new Intent(ViewMessagesActivity.this, ReplyToMessageActivity.class); 
      i.putExtra("guid", messageGuid); 
      i.putExtra("message", messageText); 
      i.putExtra("createdat", messageCreatedAt); 
      i.putExtra("sender", messageSender); 
      i.putExtra("messagereplied", messageReplied); 
      i.putExtra("messageseen", messageSeen); 
      i.putExtra("isstandalone", isStandAlone); 

      startActivity(i); 



     } 



    }// end of adapter 




} 

.

<?xml version="1.0" encoding="utf-8"?> 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingTop="5dp" 
    android:paddingBottom="5dp" 



    > 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 

    android:background="@drawable/rounded_corners_white" 
    android:layout_marginLeft="5dp" 
    android:layout_marginRight="5dp" 
    android:layout_marginTop="5dp" 
    android:layout_marginBottom="5dp" 
    > 


    <CheckBox 
    android:id="@+id/list_checkbox" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:checked="false" 
    android:focusable="false" 
    android:focusableInTouchMode="false" 
    android:background="@drawable/checkboxbg" 
    android:layout_marginLeft="5px" 
    android:layout_marginTop="5px" 

    ></CheckBox> 


    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="horizontal" 
    android:paddingBottom="10dp" 
    android:paddingTop="10dp" > 



     <TextView 
     android:id="@+id/messagecreatedat" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_weight="0.4" 
     android:text="TextView" 
     /> 

     <TextView 
     android:id="@+id/messagesenderlabel" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_weight="0.5" 
     android:gravity="right" 
     android:text="From: " 
     android:textColor="#003F87" 
     /> 

     <TextView 
     android:id="@+id/messagesender" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" 
     android:gravity="left" 
     android:text="TextView" 
     /> 


     </LinearLayout> 







    <TextView 
     android:id="@+id/messagetext" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" 
     android:gravity="center" 
     android:text="TextView" 
     android:paddingBottom="10dp" 
     /> 



</LinearLayout> 

</RelativeLayout> 

[edit1]

01-09 16:35:15.220: E/ViewMessagesActivity(1302): inside myadapter getview for messages 
01-09 16:35:15.225: E/ViewMessagesActivity(1302): (Cursor)getItem(position) = [email protected] 
01-09 16:35:15.230: E/ViewMessagesActivity(1302): inside myadapter getview for messages 
01-09 16:35:15.235: E/ViewMessagesActivity(1302): (Cursor)getItem(position) = [email protected] 
01-09 16:35:15.245: E/ViewMessagesActivity(1302): inside myadapter getview for messages 
01-09 16:35:15.250: E/ViewMessagesActivity(1302): (Cursor)getItem(position) = [email protected] 
+0

сделал курсор глобальным и использовать логические переменные, когда это необходимо делать разного рода вещи в одной переменной курсора. – Ranjit

ответ

1

У вас есть эта

Cursor c = (Cursor)getItem(position); 

Тогда

CheckBox cb = ((CheckBox)v.findViewById(R.id.list_checkbox)); 
cb.setOnCheckedChangeListener(new OnCheckedChangeListener() { 
@Override 
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
String messageGuid = c.getString(c.getColumnIndex(LoginValidate.C_MESSAGE_GUID)); 

С момента своего annonymous внутреннего класса это требует, чтобы Cursor быть final. Посмотрите на документы

http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html#accessing

Чтобы избежать этого объявить его в качестве переменной экземпляра.

private class MyAdapter extends SimpleCursorAdapter implements OnItemClickListener { 
Cursor c; 

Тогда в getView

c = (Cursor)getItem(position); 

Кроме того, вы должны рассмотреть возможность использования ViewHolder Pattern

http://developer.android.com/training/improving-layouts/smooth-scrolling.html.

Кроме того, вместо 2-х макетов LinearLayout и RelativeLayout вы могли бы использовать 1 в XML

+0

@Ragunandan Спасибо за ваш ответ. Теперь мне не нужен последний модификатор, но переменная messageGuid в onCheckedChanged всегда одинакова для каждой строки. Любые идеи почему? – turtleboy

+0

@turtleboy вам также нужно учитывать пересмотр вида просмотра. проверьте это, если это поможет http://stackoverflow.com/questions/18162931/android-get-selected-item-using-checkbox-in-listview-when-i-click-a-button – Raghunandan

+0

@Ragunandan ok спасибо, я буду взгляните на то, что вы предложили, когда у меня это получилось. Я вывел курсор с помощью Log.e (TAG, "(Cursor) getItem (position) =" + c); Результаты, которые я опубликовал в [edit1]. – turtleboy

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