2015-08-14 50 views
3

在ListView(使用自定義CursorAdapter)中,我試圖僅根據兩個ListView項目之間的日期是否更改來顯示分隔符,如下所示:as so http://i61.tinypic.com/vmqjkj.pngListView中滾動時的日期分隔符

不幸的是,當我向下滾動,暫停一秒鐘,然後再次開始滾動時,我已經將分隔符設置在錯誤的位置(例如在這裏,請參閱消失ListView中第二項中的分隔符): see the disappearance of the second item http://i61.tinypic.com/14lk7j7.jpg

或者,它可能出現在第三項中。

我所遇到的兩個主要問題:

  1. 在取決於滾動暫停的不同時間的日期分隔符的出現和消失,和
  2. 外觀日期分隔符是一個向上滾動的錯誤點。

我原則上了解到,出現這些問題,是因爲在lastDate我的適配器的行爲確實只考慮單向向下滾動,並且除了由ListView控件如何回收的意見和容器造成的。

我的問題,主要有:我怎麼能返工MyAdapter.java我的自定義的CursorAdapter或者我如何保存我的數據在MainFragment.java這樣我就可以顯示分體適當不管滾動的方向,或短暫停頓,然後rescrolls?

非常感謝你提前!

以下是MainFragment的代碼,適配器代碼以及ListView項目佈局的XML。

MyAdapter.java

package com.cpsashta.seplistview; 

import android.content.Context; 
import android.database.Cursor; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.CursorAdapter; 
import android.widget.ImageView; 
import android.widget.TextView; 

import com.cpsashta.seplistview.DbContract.DbEntry; 

public class MyAdapter extends CursorAdapter { 

    private LayoutInflater cursorInflater; 
    private Context mContext; 
    private Cursor mCursor; 

    private String lastDate; 

    TextView tvSep; 
    TextView tvName; 
    TextView tvTitle; 
    TextView tvDate; 
    TextView tvExp; 

    public MyAdapter(Context context, Cursor c, int flags) { 
     super(context,c,flags); 
     this.mContext = context; 
     this.mCursor = c; 
     cursorInflater = LayoutInflater.from(context); 
    } 

    @Override 
    public View newView(Context context, Cursor cursor, ViewGroup parent) { 
     return cursorInflater.inflate(R.layout.list_layout_1, parent, false); 

    } 

    @Override 
    public void bindView(View view, Context context, Cursor c) { 
     tvTitle = (TextView) view.findViewById(R.id.tv_title); 
     tvName = (TextView) view.findViewById(R.id.tv_name); 
     tvSep = (TextView) view.findViewById(R.id.separator); 
     tvDate = (TextView) view.findViewById(R.id.tv_date); 
     tvExp = (TextView) view.findViewById(R.id.is_expanded_view); 

     String title = c.getString(c.getColumnIndex(DbEntry.COLNAME_TITLE)); 
     String name = c.getString(c.getColumnIndex(DbEntry.COLNAME_NAME)); 
     String date = c.getString(c.getColumnIndex(DbEntry.COLNAME_DATE)); 

     tvTitle.setText(title); 
     tvName.setText(name); 
     tvDate.setText(date); 
     if (!date.equals(lastDate) || c.getPosition() == 0) { 
      tvSep.setVisibility(View.VISIBLE); 
      tvSep.setText(date); 
      tvExp.setText("true"); 
      lastDate = date; 
     } else { 
      tvSep.setVisibility(View.GONE); 
      tvExp.setText("false"); 
     } 
    } 
} 

list_layout_1.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <TextView 
     android:id="@+id/separator" 
     style="?android:attr/listSeparatorTextViewStyle" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:textColor="@android:color/white" 
     android:background="#FF0000" 
     android:visibility="gone"/> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:visibility="gone" 
     android:id="@+id/is_expanded_view"/> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:textAppearance="?android:attr/textAppearanceMedium" 
     android:text="Medium Text" 
     android:id="@+id/tv_title" 
     android:layout_gravity="center_horizontal" /> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/tv_date"/> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:textAppearance="?android:attr/textAppearanceSmall" 
     android:text="Small Text" 
     android:id="@+id/tv_name" 
     android:layout_gravity="right" /> 
</LinearLayout> 

MainFragment.java

package com.cpsashta.seplistview; 

import android.content.ContentValues; 
import android.database.Cursor; 
import android.database.sqlite.SQLiteDatabase; 
import android.support.v4.app.Fragment; 
import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Button; 
import android.widget.LinearLayout; 
import android.widget.ListView; 

import com.cpsashta.seplistview.DbContract.*; 




public class MainFragment extends Fragment { 

    String[] names = {"Dick", "Sammy", "Manuel", "Jenny", "Kirk", "Shimmy"}; 
    public static String titleSmile = "Damned crazy folks, Smile, you're on camera!"; 
    String[] titles = {"Here we go again!", titleSmile}; 
    String dateMonth = "Aug"; 

    DbHelper mDbHelper; 
    SQLiteDatabase db; 
    Button button; 

    public MainFragment() { 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View rootView = inflater.inflate(R.layout.fragment_main, container, false); 

     button = (Button) rootView.findViewById(R.id.button); 
     button.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       LinearLayout ll = (LinearLayout) v.getParent(); 
       addOneItem(ll); 
      } 
     }); 

     return rootView; 

    } 


    @Override 
    public void onViewCreated(View view, Bundle savedInstanceState) { 
     ListView lv = (ListView) view.findViewById(R.id.listview); 
     Cursor c = getAll(); 
     MyAdapter adapter = new MyAdapter(getActivity(),c,0); 
     lv.setAdapter(adapter); 

    } 

    //Occurs on button press, the view pressed is intended to be the rootView (a.k.a. the LinearLayout housing the ListView and button) 
    public void addOneItem(View view) { 
     newItemToDb(); 
     ListView lv = (ListView) view.findViewById(R.id.listview); 
     MyAdapter adapter = (MyAdapter) lv.getAdapter(); 
     adapter.notifyDataSetChanged(); 
    } 

    //Adds random name, title, and date to the database 
    public void newItemToDb() { 
     if (db == null || !db.isOpen()) { 
      if (mDbHelper == null) { 
       mDbHelper = new DbHelper(getActivity()); 
      } 
      db = mDbHelper.getWritableDatabase(); 
     } 

     ContentValues values = new ContentValues(); 
     int nameVal = (int)(Math.random() * names.length); 
     values.put(DbEntry.COLNAME_NAME, names[nameVal]); 

     int titleVal = (int) (Math.random() * titles.length); 
     values.put(DbEntry.COLNAME_TITLE, titles[titleVal]); 

     //Chooses a date from August 1 to August 10 
     //int dateDay = (int)(Math.random() * 10 + 1); 
     //FOR NOW choosing the date of Aug 1 or 2 only 
     int dateDay = (int)(Math.random() * 2 + 1); 
     String date = dateMonth + " " + dateDay; 
     values.put(DbEntry.COLNAME_DATE, date); 


     db.insert(DbEntry.TABLE_NAME, null, values); 
     db.close(); 
    } 

    public Cursor getAll() { 
     if (db == null || !db.isOpen()) { 
      if (mDbHelper == null) { 
       mDbHelper = new DbHelper(getActivity()); 
      } 
      db = mDbHelper.getWritableDatabase(); 
     } 

     String[] projection = { DbEntry._ID, 
       DbEntry.COLNAME_TITLE, 
       DbEntry.COLNAME_NAME, 
       DbEntry.COLNAME_DATE 
     }; 

     String sortOrder = null; 

     //TODO delete the sortOrder below 
     //String sortOrder = RecordingEntry.COLNAME_TAG_FULL 
     //  + " DESC"; 
     String[] selectionArgs = null; 
     String selection = null; // Setting this to null 

     Cursor c = db.query(DbEntry.TABLE_NAME, 
       projection, 
       selection, 
       selectionArgs, 
       null, // don't group the rows 
       null, // don't filter by row groups 
       sortOrder 
     ); 

     return c; 
    } 

} 

編輯:我已經投入使用的基礎上,@ NT的建議解決方案,取代MainFragment與下面的bindView部分的結尾:

 String lastDate = ""; 
     int position = c.getPosition(); 
     if (position != 0) { 
      c.moveToPosition(position - 1); 
      lastDate = c.getString(c.getColumnIndex(DbEntry.COLNAME_DATE)); 
      c.moveToPosition(position); 
     } 
     if (position == 0 || !date.equals(lastDate)) { 
      separator.setVisibility(View.VISIBLE); 
      separator.setText(date); 
     } else { 
      separator.setVisibility(View.GONE); 
     } 
+0

正是我在找什麼。 Thanx夥伴。 – Androidster

回答

2

你無法控制的順序的newView/bindView被調用。假設您在屏幕上顯示項目10-20,並且最後一個畫面是一個表格位置20,因此您的lastDate將指向該位置。現在,您向上滾動,系統將要求您抽取項目#9。在這一點上,您可以比較項目#9和lastDate,指向項目#20,這不是您想要的。

要修復您需要將光標移動到前一位置(mCursor.moveToPosition(position - 1))的事情,並檢查當前項目是否與列表中的前一個項目相對,而不是針對先前請求的項目進行繪製。

+0

非常感謝!我已將上面使用的特定代碼作爲編輯。 – cshadowstar