サンプルアプリケーションの目的は、SQLiteデータベースのアイテムを表示することですが、 (それ以外の場合は、2番目のテキストビューを表示します)。Androidリスト内のレイアウト内の1つのビューを非表示にする方法データベースカーソルアダプタによってバックアップされたビュー
問題は正しいものを隠さないということです。また、スクロール操作によってアイテムが表示されなくなり、表示に戻ると、2番目のテキストビューが隠され、様々なリストアイテムに不安定に表示されます。
隠しフラグが20、15、項目5、10に設定され、ここでそれが来るアップする方法ですされています: スクロールダウン、他のさまざまな奇妙なアイテムが隠されている、そしてそれはしていないようです毎回同じである。エントリ14、エントリ16は、例えば、隠される。
先頭にスクロールすると、最初の項目のセットに、同じ隠れた2行目がなくなることがわかります。
そして、エントリーの全体の新しいセットを前後にスクロール隠されています。全くランダムではありませんが、不可解です。あなたはそれを信じるためにそれを見なければなりません。
このサンプルが基づいている「実際の」アプリケーション(ここには表示されていません)は、実際にはImageViewを表示したり隠したりしようとしていますが、TextViewを隠すのと同じ種類の問題があります。 。
以下はアプリケーションです。 この狂ったことを実行したい場合は、(、サンプルデータを含む)を含める必要があります。それとも、githubの上でそれを見つけることができます。https://github.com/sengsational/LvCaApp
LvCaActivity.java
:
public class LvCaActivity extends AppCompatActivity {
private SimpleCursorAdapter dataAdapter;
private DbAdapter dbHelper;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lv_ca);
dbHelper = new DbAdapter(this);
dbHelper.open();
dbHelper.deleteAll();
dbHelper.insertSome();
Cursor bCursor = dbHelper.fetchAll(DbAdapter.bColumns);
dataAdapter = new MySimpleCursorAdapter(
this, R.layout.b_item,
bCursor,
DbAdapter.bColumns,
ViewHolder.viewsArray,
0);
ListView listView = (ListView) findViewById(R.id.listView1);
listView.setAdapter(dataAdapter);
}
}
activity_lv_ca.xml
:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical">
<ListView android:id="@+id/listView1" android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
b_item.xml
:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="6dip"
android:id="@+id/b_item_layout">
<TextView
android:id="@+id/bName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:textAppearance="?android:attr/textAppearanceListItem"
android:ellipsize="end"
android:singleLine="true"
android:paddingTop="30dp"/>
<TextView
android:id="@+id/bSecondLine"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/bName"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="@+id/bDbItem"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:visibility="gone"
/>
<TextView
android:id="@+id/bHidden"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:visibility="gone"
/>
</RelativeLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.company.cpp.lvcaapp"
xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".LvCaActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
DbAdapter.java
:
public class DbAdapter {
private static final String TAG = "DbAdapter";
private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;
private static final String DATABASE_NAME = "adbname";
private static final String SQLITE_TABLE = "atablename";
private static final int DATABASE_VERSION = 1;
private final Context mCtx;
public static final String[] bColumns = new String[] {
"_id",
"NAME",
"SECOND_LINE",
"HIDDEN",
};
private static final String DATABASE_CREATE =
"CREATE TABLE if not exists " + SQLITE_TABLE + " (" +
"_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"NAME TEXT, " +
"SECOND_LINE, " +
"HIDDEN" +
");";
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.w(TAG, DATABASE_CREATE);
db.execSQL(DATABASE_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + SQLITE_TABLE);
onCreate(db);
}
}
public DbAdapter(Context ctx) {
this.mCtx = ctx;
}
public DbAdapter open() throws SQLException {
mDbHelper = new DatabaseHelper(mCtx);
mDb = mDbHelper.getWritableDatabase();
return this;
}
public void close() {
if (mDbHelper != null) {
mDbHelper.close();
}
}
public Cursor fetchAll(String[] fields) {
Cursor mCursor = mDb.query(SQLITE_TABLE, fields, null, null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
public void insertSome() {
AListItem.getInstance();
String sampleData = "[{\"name\":\"Entry 1\",\"second_line\":\"Second Line 1\",\"hidden\":\"F\"},{\"name\":\"Entry 2\",\"second_line\":\"Second Line 2\",\"hidden\":\"F\"},{\"name\":\"Entry 3\",\"second_line\":\"Second Line 3\",\"hidden\":\"F\"},{\"name\":\"Entry 4\",\"second_line\":\"Second Line 4\",\"hidden\":\"F\"},{\"name\":\"EntryH 5\",\"second_line\":\"Second Line 5\",\"hidden\":\"T\"},{\"name\":\"Entry 6\",\"second_line\":\"Second Line 6\",\"hidden\":\"F\"},{\"name\":\"Entry 7\",\"second_line\":\"Second Line 7\",\"hidden\":\"F\"},{\"name\":\"Entry 8\",\"second_line\":\"Second Line 8\",\"hidden\":\"F\"},{\"name\":\"Entry 9\",\"second_line\":\"Second Line 9\",\"hidden\":\"F\"},{\"name\":\"EntryH 10\",\"second_line\":\"Second Line 10\",\"hidden\":\"T\"},{\"name\":\"Entry 11\",\"second_line\":\"Second Line 11\",\"hidden\":\"F\"},{\"name\":\"Entry 12\",\"second_line\":\"Second Line 12\",\"hidden\":\"F\"},{\"name\":\"Entry 13\",\"second_line\":\"Second Line 13\",\"hidden\":\"F\"},{\"name\":\"Entry 14\",\"second_line\":\"Second Line 14\",\"hidden\":\"F\"},{\"name\":\"EntryH 15\",\"second_line\":\"Second Line 15\",\"hidden\":\"T\"},{\"name\":\"Entry 16\",\"second_line\":\"Second Line 16\",\"hidden\":\"F\"},{\"name\":\"Entry 17\",\"second_line\":\"Second Line 17\",\"hidden\":\"F\"},{\"name\":\"Entry 18\",\"second_line\":\"Second Line 18\",\"hidden\":\"F\"},{\"name\":\"Entry 19\",\"second_line\":\"Second Line 19\",\"hidden\":\"F\"},{\"name\":\"EntryH 20\",\"second_line\":\"Second Line 20\",\"hidden\":\"T\"},{\"name\":\"Entry 21\",\"second_line\":\"Second Line 21\",\"hidden\":\"F\"},{\"name\":\"Entry 22\",\"second_line\":\"Second Line 22\",\"hidden\":\"F\"},{\"name\":\"Entry 23\",\"second_line\":\"Second Line 23\",\"hidden\":\"F\"}]";
String[] items = sampleData.split("\\},\\{");
for(String item: items){
AListItem.clear();
AListItem.load(item);
if(AListItem.getName().contains("Hide")){
AListItem.setHidden("T");
}
mDb.insert(SQLITE_TABLE, null, AListItem.getContentValues());
ContentValues values = AListItem.getContentValues();
Log.v(TAG, "values.toString()" + values.toString());
}
}
public boolean deleteAll() {
int doneDelete = 0;
doneDelete = mDb.delete(SQLITE_TABLE, null , null);
Log.w(TAG, Integer.toString(doneDelete));
return doneDelete > 0;
}
}
AListItem.java
:
public class AListItem {
static String rawInputString;
static String name;
static String second_line;
static String hidden;
static AListItem aListItem;
private AListItem() {
}
public static AListItem getInstance(){
if (aListItem == null) {
aListItem = new AListItem();
}
return aListItem;
}
public static void clear() {
rawInputString = null;
name = null;
second_line = null;
hidden = null;
}
public static ContentValues getContentValues() {
ContentValues values = new ContentValues();
values.put("NAME", name);
values.put("SECOND_LINE", second_line);
values.put("HIDDEN", hidden);
return values;
}
public static void load(String string) {
StringBuffer buf = new StringBuffer(string);
if (buf.substring(0,2).equals("[{")){
buf.delete(0,2);
}
rawInputString = buf.toString();
parse();
}
public static void parse() {
if (rawInputString == null) {
System.out.println("nothing to parse");
return;
}
rawInputString = rawInputString.replaceAll("\"\\:null,", "\"\\:\"null\",");
String[] nvpa = rawInputString.split("\",\"");
for (String nvpString : nvpa) {
String[] nvpItem = nvpString.split("\":\"");
if (nvpItem.length < 2) continue;
String identifier = nvpItem[0].replaceAll("\"", "");
String content = nvpItem[1].replaceAll("\"", "");
switch (identifier) {
case "name":
setName(content);
break;
case "second_line":
setSecond_line(content);
break;
case "hidden":
setHidden(content);
break;
default:
System.out.println("nowhere to put [" + nvpItem[0] + "] " + nvpString + " raw: " + rawInputString);
break;
}
}
}
public static String getName() {
return name;
}
public static void setName(String name) { AListItem.name = name; }
public static void setSecond_line(String second_line) {
AListItem.second_line = second_line;
}
public static String getSecond_line() {
return second_line;
}
public static void setHidden(String hidden) {
AListItem.hidden = hidden;
}
public static String getHidden() {
return hidden;
}
public String toString() {
return getName() + ", " +
getSecond_line() + ", " +
getHidden();
}
}
MySimpleCursorAdapter.java
:
public class MySimpleCursorAdapter extends SimpleCursorAdapter {
Context context;
Cursor cursor;
public static final String TAG = "MySimpleCursorAdapter";
public MySimpleCursorAdapter(Context context, int layout, Cursor cursor, String[] from, int[] to, int flags) {
super(context, layout, cursor, from, to, flags);
this.context = context;
this.cursor = cursor;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.v(TAG,"getView() >>>>>>STARTING");
ViewHolder viewHolder;
LayoutInflater inflater = LayoutInflater.from(context);
if (null == convertView || null == convertView.getTag()) {
convertView = inflater.inflate(R.layout.b_item, null);
viewHolder = new ViewHolder(convertView);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
for (int i = 0; i < cursor.getColumnCount(); i++) {
Log.v(TAG, "getView cursor " + i + ": " + cursor.getString(i));
}
String hidden = cursor.getString(ViewHolder.HIDDEN);
if (hidden == null) hidden = "F";
Log.v(TAG,"Hidden State: " + hidden);
switch (hidden) {
case "F":
viewHolder.showSecondLine(); // DRS 20160827 - Added line suggested by aiwiguna
break;
case "T":
Log.v(TAG,">>>>>Hidden was TRUE<<<<<<<: " + cursor.getString(ViewHolder.NAME));
viewHolder.hideSecondLine();
break;
}
convertView.setTag(viewHolder);
View returnView = super.getView(position, convertView, parent);
Log.v(TAG,"getView() ENDING<<<<<<<<<");
return returnView;
}
}
ViewHolder.java
:
class ViewHolder {
public static final String TAG = "ViewHolder";
public static final int DB_ITEM = 0;
public static final int NAME = 1;
public static final int SECOND_LINE = 2;
public static final int HIDDEN = 3;
public static final int[] viewsArray = new int[] {
R.id.bDbItem,
R.id.bName,
R.id.bSecondLine,
R.id.bHidden,
};
public static final TextView[] textViewArray = new TextView[viewsArray.length];
public ViewHolder(final View root) {
Log.v(TAG, "ViewHolder constructor");
for (int i = 0; i < viewsArray.length; i++) {
textViewArray[i] = (TextView) root.findViewById(viewsArray[i]);
Log.v(TAG, " textViewArray[" + i + "]: " + textViewArray[i]);
}
}
public void hideSecondLine() {
textViewArray[SECOND_LINE].setVisibility(View.INVISIBLE);
}
//DRS 20160827 - Addition recommended by aiwiguna
public void showSecondLine() {
textViewArray[SECOND_LINE].setVisibility(View.VISIBLE);
}
}
「RecyclerView」へのポインタありがとうございます。具体的にどのようにすればよいでしょうか? – Dale
この単純な例では複数のレイアウトが論理的に見えますが、実際のアプリケーションではwhiこのサンプルアプリケーションでは、1つのTextViewを隠すほど簡単ではないので、効率的に管理するレイアウトが多すぎます。 – Dale