我向学者致敬。我对自定义列表视图感到很尴尬。在滚动时,我在listview中显示的值会发生变化。点击任何listitem,它会显示当前可见的第一条记录的数据。请帮帮我。我不知道如何处理 getView()方法来纠正这个错误。
我的java代码:
package com.addictioncounterapp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class StartActivity extends Activity
{
ListView listview1;
static SQLiteDatabase database;
private Addiction[] addictions;
private ArrayAdapter<Addiction> listAdapter ;
ArrayList<Addiction> addictionList;
ImageView iv_settings;
static int limit;
static String attribute;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
createDB();
loadDB();
iv_settings = (ImageView) findViewById(R.id.imageViewStart);
iv_settings.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
Intent intent = new Intent(StartActivity.this, Settings.class);
startActivity(intent);
}
}
);
manageList();
listview1 = (ListView) findViewById(R.id.listViewStart);
if(addictionList.isEmpty())
{
Toast.makeText(getBaseContext(), "No records of Addiction found...Go to 'Settings > Manage Addictions > Add' to create new addiction.", Toast.LENGTH_LONG).show();
}
else
{
listview1.setAdapter(listAdapter);
}
listview1.setOnItemClickListener(new OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
{
View parentView = (View) arg1.getParent();
String textview1 = ((TextView) parentView.findViewById(R.id.textViewStartAddictionName)).getText().toString();
Intent intent = new Intent(StartActivity.this, AddictionDetails.class);
intent.putExtra("cat_name", textview1);
startActivity(intent);
}
}
);
}
private void createDB()
{
database = openOrCreateDatabase("AddictionCounter.db", SQLiteDatabase.CREATE_IF_NECESSARY, null);
database.setLocale(Locale.getDefault());
database.setVersion(1);
try
{
String create_table_1 = "create table if not exists category (cat_id INTEGER PRIMARY KEY AUTOINCREMENT," +
" cat_server_id INTEGER," +
" cat_name TEXT UNIQUE," +
" parent_cat_id INTEGER," +
" is_delete INTEGER," +
" is_sync INTEGER," +
" creation_date TEXT," +
" update_date TEXT)";
database.execSQL(create_table_1);
String create_table_2 = "create table if not exists category_attribute (cat_attribute_id INTEGER PRIMARY KEY AUTOINCREMENT," +
" cat_attribute_server_id INTEGER," +
" cat_server_id INTEGER," +
" cat_id INTEGER," +
" cat_attribute_name TEXT," +
" cat_attribute_unit INTEGER," +
" cat_limit INTEGER," +
" is_delete INTEGER," +
" is_sync INTEGER," +
" creation_date TEXT," +
" update_date TEXT)";
database.execSQL(create_table_2);
String create_table_3 = "create table if not exists category_limit (limit_id INTEGER PRIMARY KEY AUTOINCREMENT," +
" limit_server_id INTEGER," +
" cat_id INTEGER," +
" limit_count INTEGER," +
" is_delete INTEGER," +
" is_sync INTEGER," +
" creation_date TEXT," +
" update_date TEXT)";
database.execSQL(create_table_3);
String create_table_4 = "create table if not exists counter (counter_id INTEGER PRIMARY KEY AUTOINCREMENT," +
" counter_server_id INTEGER," +
" cat_id INTEGER," +
" cat_attribute_id INTEGER," +
" cat_attribute_unit INTEGER," +
" counter_entry_date TEXT," +
" counter_entry_date_time TEXT," +
" is_delete INTEGER," +
" is_sync INTEGER)";
database.execSQL(create_table_4);
}
catch(SQLException e)
{
Log.e("SQLException","The SQL string is invalid. ");
Toast.makeText(getBaseContext(), "SQLException: The SQL string is invalid.", Toast.LENGTH_SHORT).show();
}
database.close();
}
private void loadDB()
{
database = openOrCreateDatabase("AddictionCounter.db", SQLiteDatabase.OPEN_READWRITE, null);
}
private void manageList()
{
String addictionName="", todaysCount="", dailyLimit="", unit="";
addictionList = new ArrayList<Addiction>();
AddictionsData objAddictionsData = new AddictionsData();
Cursor cursor = database.query("category", new String[]{"cat_id"}, null, null, null, null, null);
if(cursor.getCount() > 0)
{
while(cursor.moveToNext())
{
int tmp_cat_id = cursor.getInt(0);
addictionName = objAddictionsData.getAddictionName(tmp_cat_id);
todaysCount = objAddictionsData.getTodaysCount(tmp_cat_id);
dailyLimit = objAddictionsData.getDailyLimit(tmp_cat_id);
unit = objAddictionsData.getUnit(tmp_cat_id);
addictions = new Addiction[]{new Addiction(tmp_cat_id, addictionName, todaysCount, dailyLimit, unit)};
addictionList.addAll( Arrays.asList(addictions) );
}
cursor.close();
}
listAdapter = new AddictionArrayAdapter(this, addictionList);
database.close();//---------------------------
}
public int insertIntoCounter(int id)
{
loadDB();//------------------------------------
//---------------------insert the record-------------------
ContentValues values = new ContentValues();
int cat_attribute_id = 0;
int cat_attribute_unit = 0;
Cursor cursor1 = database.query("category_attribute", new String[]{"cat_attribute_id", "cat_attribute_unit"}, "cat_id=?", new String[]{id+""}, null, null, null);
if(cursor1.getCount() > 0)
{
while(cursor1.moveToNext())
{
cat_attribute_id = cursor1.getInt(0);
cat_attribute_unit = cursor1.getInt(1);
}
cursor1.close();
}
Calendar c = Calendar.getInstance();
SimpleDateFormat dtf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
String currentTimeAndDate = dtf.format(c.getTime());
SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");
String currentDate = df.format(c.getTime());
values.put("counter_server_id", 0);
values.put("cat_id", id);
values.put("cat_attribute_id", cat_attribute_id);
values.put("cat_attribute_unit", cat_attribute_unit);
values.put("counter_entry_date", currentDate);
values.put("counter_entry_date_time", currentTimeAndDate);
values.put("is_delete", 0);
values.put("is_sync", 0);
try
{
database.insert("counter", null, values);
}
catch(Exception e)
{
Log.e("Exception", e+"");
}
//------------------------LIMIT FUNCTIONSLITY---------------------
//------------------------fetching attribute name
cursor1 = database.query("category_attribute", new String[]{"cat_attribute_name"}, "cat_id=?", new String[]{id+""}, null, null, null);
if(cursor1.getCount() > 0)
{
while(cursor1.moveToNext())
attribute = cursor1.getString(0);
cursor1.close();
}
//------------------------fetching limit
cursor1 = database.query("category_limit", new String[]{"limit_count"}, "cat_id=?", new String[]{id+""}, null, null, null);
if(cursor1.getCount() > 0)
{
while(cursor1.moveToNext())
limit = cursor1.getInt(0);
cursor1.close();
}
//--------------------------fetching todays count
int todays_count = 0;
Calendar cal1 = Calendar.getInstance();
SimpleDateFormat dateFormat1 = new SimpleDateFormat("dd/MM/yyyy");
String todays_date = dateFormat1.format(cal1.getTime());
cursor1 = database.rawQuery("select sum(cat_attribute_unit) from counter where cat_id ="+id+" AND counter_entry_date = '"+todays_date+"';", null);
while(cursor1.moveToNext())
todays_count = cursor1.getInt(0);
//---------------------sending acknowledgement
int ack;
if(todays_count < limit)
ack = 0;
else if(todays_count == limit)
ack = 1;
else
ack = 2;
return ack;
}
public static class Addiction
{
private String cat_name = "", cat_todays_count="", cat_daily_limit="", cat_attribute_unit="";
private int cat_id = 0;
public Addiction(int id, String catName, String catTodaysCount, String catDailyLimit, String catAttributeUnit)
{
cat_id = id;
cat_name = catName ;
cat_todays_count = catTodaysCount;
cat_daily_limit = catDailyLimit;
cat_attribute_unit = catAttributeUnit;
}
public int getId()
{
return cat_id;
}
public String getCatName()
{
return cat_name;
}
public String getCatTodaysCount()
{
return cat_todays_count;
}
public String getCatDailyLimit()
{
return cat_daily_limit;
}
public String getCatAttributeUnit()
{
return cat_attribute_unit;
}
}
private static class AddictionViewHolder
{
private ImageView imageViewAddictionLog ;
private TextView textViewAddictionName, textViewTodaysCount, textViewDailyLimit, textViewAttributeUnit ;
public AddictionViewHolder( ImageView iv_log, TextView tv_addiction_name, TextView tv_todays_count, TextView tv_daily_limit, TextView tv_attribute_count)
{
imageViewAddictionLog = iv_log;
textViewAddictionName = tv_addiction_name;
textViewTodaysCount = tv_todays_count;
textViewDailyLimit = tv_daily_limit;
textViewAttributeUnit = tv_attribute_count;
}
public ImageView getImageViewAddLog()
{
return imageViewAddictionLog;
}
public TextView getTextViewAddictionName()
{
return textViewAddictionName;
}
public TextView getTextViewTodaysCount()
{
return textViewTodaysCount;
}
public TextView getTextViewDailyLimit()
{
return textViewDailyLimit;
}
public TextView getTextViewAttributeUnit()
{
return textViewAttributeUnit;
}
}
private static class AddictionArrayAdapter extends ArrayAdapter<Addiction>
{
private LayoutInflater inflater;
StartActivity objStartActivity = new StartActivity();
public AddictionArrayAdapter( Context context, List<Addiction> addictionList )
{
super( context, R.layout.single_row_start, R.id.textViewStartAddictionName, addictionList );
inflater = LayoutInflater.from(context);
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
Addiction addiction = (Addiction) this.getItem( position );
ImageView imageViewAddLog ;
TextView textViewAN ;
final TextView textViewTC;
final TextView textViewDL;
final TextView textViewU;
if(convertView == null)
{
convertView = inflater.inflate(R.layout.single_row_start, null);
imageViewAddLog = (ImageView) convertView.findViewById(R.id.imageViewStartAdd);
textViewAN = (TextView) convertView.findViewById(R.id.textViewStartAddictionName);
textViewTC = (TextView) convertView.findViewById(R.id.textViewStartTodaysCountValue);
textViewDL = (TextView) convertView.findViewById(R.id.textViewStartDailyLimitCount);
textViewU = (TextView) convertView.findViewById(R.id.textViewStartAddictionUnit);
imageViewAddLog.setFocusable(false);
imageViewAddLog.setFocusableInTouchMode(false);
imageViewAddLog.setClickable(true);
convertView.setTag( new AddictionViewHolder(imageViewAddLog, textViewAN, textViewTC, textViewDL, textViewU) );
imageViewAddLog.setOnClickListener( new View.OnClickListener()
{
public void onClick(View v)
{
ImageView ib = (ImageView) v ;
Addiction addiction = (Addiction) ib.getTag();
int tmp_cat_id = addiction.getId();
int ack = objStartActivity.insertIntoCounter(tmp_cat_id);
String cat_name = addiction.getCatName();
switch(ack)
{
case 0:
String message0 = "Record added Successfully.";
customShowDialog(message0, tmp_cat_id);
break;
case 1:
String message1 = "Please stop "+cat_name+". Today you have already added "+limit+" "+ attribute+". Your daily limit is "+limit+" "+attribute+".";
customShowDialog(message1, tmp_cat_id);
break;
case 2:
String message2 = "Please stop "+cat_name+". Today you have already added "+limit+" "+ attribute+". You have crossed your daily limit of "+limit+" "+attribute+".";
customShowDialog(message2, tmp_cat_id);
break;
}
}
private void customShowDialog(String message, final int cat_id)
{
AlertDialog.Builder adb = new Builder(getContext());
adb.setTitle("Success !!!");
adb.setMessage(message);
adb.setIcon(R.drawable.ic_launcher);
adb.setPositiveButton("Ok",new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface arg0, int arg1)
{
arg0.cancel();
AddictionsData ad = new AddictionsData();
textViewTC.setText( ad.getTodaysCount(cat_id));
textViewDL.setText( ad.getDailyLimit(cat_id));
textViewU.setText( ad.getUnit(cat_id));
}
}
);
AlertDialog ad = adb.create();
ad.show();
}
}
);
}
else
{
AddictionViewHolder viewHolder = (AddictionViewHolder) convertView.getTag();
imageViewAddLog = viewHolder.getImageViewAddLog();
textViewAN = viewHolder.getTextViewAddictionName();
textViewTC = viewHolder.getTextViewTodaysCount();
textViewDL = viewHolder.getTextViewDailyLimit();
textViewU = viewHolder.getTextViewAttributeUnit();
}
imageViewAddLog.setTag( addiction );
textViewAN.setText( addiction.getCatName());
textViewTC.setText( addiction.getCatTodaysCount());
textViewDL.setText( addiction.getCatDailyLimit());
textViewU.setText( addiction.getCatAttributeUnit());
return convertView;
}
}
public static class AddictionsData
{
Cursor cursor;
String getAddictionName(int cat_id)
{
String tmp_name = null;
cursor = database.query("category", new String[]{"cat_name"}, "cat_id=?", new String[]{cat_id+""}, null, null, null);
if(cursor.getCount() > 0)
{
while(cursor.moveToNext())
{
tmp_name = cursor.getString(0);
}
cursor.close();
}
return tmp_name;
}
String getTodaysCount(int cat_id)
{
String todaysCount = null;
int todays_count = 0;
Calendar cal1 = Calendar.getInstance();
SimpleDateFormat dateFormat1 = new SimpleDateFormat("dd/MM/yyyy");
String todays_date = dateFormat1.format(cal1.getTime());
cursor = database.rawQuery("select sum(cat_attribute_unit) from counter where cat_id ="+cat_id+" AND counter_entry_date = '"+todays_date+"';", null);
if(cursor.getCount() > 0)
{
while(cursor.moveToNext())
{
todays_count = cursor.getInt(0);
}
cursor.close();
}
String attribute = null;
cursor = database.query("category_attribute", new String[]{"cat_attribute_name"}, "cat_id=?", new String[]{cat_id+""}, null, null, null);
if(cursor.getCount() > 0)
{
while(cursor.moveToNext())
{
attribute = cursor.getString(0);
}
cursor.close();
}
todaysCount = todays_count+" "+attribute;
return todaysCount;
}
String getDailyLimit(int cat_id)
{
String dailyLimit;
int daily_limit = 0;
cursor = database.query("category_limit", new String[]{"limit_count"}, "cat_id=?", new String[]{cat_id+""}, null, null, null);
if(cursor.getCount() > 0)
{
while(cursor.moveToNext())
daily_limit = cursor.getInt(0);
cursor.close();
}
String attribute = null;
cursor = database.query("category_attribute", new String[]{"cat_attribute_name"}, "cat_id=?", new String[]{cat_id+""}, null, null, null);
if(cursor.getCount() > 0)
{
while(cursor.moveToNext())
{
attribute = cursor.getString(0);
}
cursor.close();
}
dailyLimit = daily_limit+ " "+attribute;
return dailyLimit;
}
String getUnit(int cat_id)
{
String unit;
int _unit = 0;
cursor = database.query("category_attribute", new String[]{"cat_attribute_unit"}, "cat_id=?", new String[]{cat_id+""}, null, null, null);
if(cursor.getCount() > 0)
{
while(cursor.moveToNext())
_unit = cursor.getInt(0);
cursor.close();
}
String attribute = null;
cursor = database.query("category_attribute", new String[]{"cat_attribute_name"}, "cat_id=?", new String[]{cat_id+""}, null, null, null);
if(cursor.getCount() > 0)
{
while(cursor.moveToNext())
{
attribute = cursor.getString(0);
}
cursor.close();
}
unit = _unit+ " "+attribute;
return unit;
}
}
}
我的主要布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/main_bg_edited" >
<ImageView
android:id="@+id/imageViewStart"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:src="@drawable/setting_icon"
android:layout_marginRight="7dp" />
<ListView
android:id="@+id/listViewStart"
android:layout_width="290dp"
android:layout_height="wrap_content"
android:layout_below="@+id/imageViewStart"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:divider="@android:color/transparent"
android:dividerHeight="10dp"
android:drawSelectorOnTop="true" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/imageViewStart"
android:layout_centerHorizontal="true"
android:text="Addictions"
style="@style/header_style" />
</RelativeLayout>
我正在给视图充气的布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/box_midbg" >
<TextView
android:id="@+id/textViewStartTodaysCountValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textViewStartAddictionName"
android:layout_toRightOf="@+id/textViewTodaysCount"
android:text=" TextView"
android:textSize="10sp"
android:textColor="#ffffff" />
<TextView
android:id="@+id/textViewStartDailyLimitCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="@+id/textViewStartTodaysCountValue"
android:layout_alignTop="@+id/textViewDailyLimit"
android:text="TextView"
android:textSize="10sp"
android:textColor="#ffffff" />
<TextView
android:id="@+id/textViewStartAddictionUnit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@+id/textViewStartTodaysCountValue"
android:layout_marginRight="15dp"
android:text="TextView"
android:textColor="#ffffff"
android:textSize="10sp" />
<TextView
android:id="@+id/textViewStartAddictionName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/imageViewStartAdd"
android:layout_alignParentLeft="true"
android:layout_marginLeft="15dp"
android:text="TextView"
android:textColor="#ffffff"
android:textSize="20sp" />
<TextView
android:id="@+id/textViewTodaysCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/textViewStartAddictionUnit"
android:layout_alignLeft="@+id/textViewStartAddictionName"
android:text="Today's Counts : "
android:textColor="#ffffff"
android:textSize="10sp" />
<TextView
android:id="@+id/textViewDailyLimit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textViewTodaysCount"
android:layout_below="@+id/textViewTodaysCount"
android:text="Daily Limit :"
android:textColor="#ffffff"
android:textSize="10sp" />
<ImageView
android:id="@+id/imageViewStartAdd"
android:layout_width="25sp"
android:layout_height="25sp"
android:layout_alignRight="@+id/textViewStartAddictionUnit"
android:layout_centerVertical="true"
android:clickable="true"
android:src="@drawable/add_btn" />
</RelativeLayout>
答案 0 :(得分:1)
您不应该将数据存储在视图中,因为视图会被回收,而且几乎可以肯定会发生什么。以下
Addiction addiction = (Addiction) ib.getTag();
....
imageViewAddLog.setTag( addiction );
不可取。更好的方法是让列表视图处理点击,以便您可以知道单击了哪个视图以及与视图位置对应的正确Addiction
对象。
myList.setOnItemClickListener(
new OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> arg0, View view,
int position, long id) {
Addiction addiction = (Addiction) myList.getItemAtPosition(position);
...rest of code...
}
}
);
答案 1 :(得分:0)
请将所有其他代码放在
之后convertView.setTag( new AddictionViewHolder(imageViewAddLog, textViewAN, textViewTC, textViewDL, textViewU) );
在if
之外,尝试从代码中删除else
。
else
之后,if
的其余代码将相同。请注意,当convertview
为空时,请创建一个新的holder
并设置为Tag
。然后在Tag
不为空时从convertview
检索该对象。并在之后编写所有其他代码,例如将值设置为视图等
AddictionViewHolder viewHolder = (AddictionViewHolder) convertView.getTag();