不幸的是,我真的认为我必须稍微广泛地解释一下我的情况。
我正在编写一个关于古代拉丁语的安卓应用程序:我的目标是向用户展示拉丁动词的整个变位,并在他们搜索特定的变形形式时为他们提供正确的语言分析。这是我的清单。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android_application.app_name"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ConjActivity"
android:label="@string/app_name"
android:parentActivityName=".MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.android_application.app_name.MainActivity"/>
</activity>
</application>
</manifest>
只要知道,为了实现第一个目标,我会自动将每个动词的所有形式创建为字符串,并且每个变位都显示为一个简单的 ListView,只有一个 TextView 字符串作为项目:一个项目 = 一个变形的口头形式。
现在,我需要自定义我的项目,有时修改它们的 textStyle,有时修改它们的对齐方式等。为此,我以这种方式创建了我的自定义 ListAdapter:
private static class ConjAdapter extends ArrayAdapter<String> {
private ArrayList<Long> ids;
private HashMap<String, Long> mIdMap;
public ConjAdapter(Context context, int textViewResourceId, List<String> objects) {
super(context, textViewResourceId, objects);
ids = new ArrayList<Long>();
mIdMap = new HashMap<String, Long>();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
ViewHolder holder;
if(convertView==null){
convertView = LayoutInflater.from(context).inflate(R.layout.simple_list_item_1, parent, false);
holder = new ViewHolder();
holder.txt = (TextView) convertView.findViewById(R.id.text1);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
long id = getItemId(position);
if(sel_vb!=null){
if(ids.contains(id)){ v.setBackgroundColor(context.getResources().getColor(R.color.row_bckgr_RED));
} else {
v.setBackgroundColor(Color.TRANSPARENT);
}
}
for(Map.Entry<String, Long> map : mIdMap.entrySet()){
if(id==map.getValue()){
holder.txt.setText(map.getKey());
break;
}
}
String item = (String) holder.txt.getText();
if(item.equals(context.getResources().getString(R.string.ind))||
item.equals(context.getResources().getString(R.string.subj))||
item.equals(context.getResources().getString(R.string.imp))||
item.equals(context.getResources().getString(R.string.inf))||
item.equals(context.getResources().getString(R.string.pt))||
item.equals(context.getResources().getString(R.string.ger))||
item.equals(context.getResources().getString(R.string.gerv))||
item.equals(context.getResources().getString(R.string.sup))){
holder.txt.setGravity(Gravity.CENTER);
holder.txt.setTextSize(20f);
holder.txt.setTypeface(null, Typeface.BOLD);
} else if(item.equals(context.getResources().getString(R.string.pres))||
item.equals(context.getResources().getString(R.string.impf))||
item.equals(context.getResources().getString(R.string.fut))||
item.equals(context.getResources().getString(R.string.pf))||
item.equals(context.getResources().getString(R.string.ppf))||
item.equals(context.getResources().getString(R.string.futant))){
holder.txt.setTypeface(null, Typeface.ITALIC);
holder.txt.setTextSize(19f);
} else {
holder.txt.setPadding(10, 0, 0, 0);
}
return convertView;
}
@Override
public long getItemId(int position) {
String item = getItem(position);
return mIdMap.get(item);
}
@Override
public boolean hasStableIds() {
return true;
}
static class ViewHolder {
TextView txt;
}
}
问题是,在第 19 项之后出现了问题,因为我没有收到错误消息,也没有应用程序崩溃,但是我的自定义代码不再起作用,并且应该具有某些功能的项目具有相反的其他功能。当我上下滚动列表时,这种情况会变得更糟。
在我阅读之后,我真的认为这个问题与我的自定义适配器的 getView() 调用的 convertview 变量的回收目标有关。
这是我的问题:为什么即使使用稳定的 id(我将其与关联的项目字符串一起存储在 mIdMap 中)也会发生这种情况,以及如何将我的项目与不正确的位置变量分离?
更新
这是我用来填充 mIdMap 和 ids 的代码:
HashMap<String, Long> tempMap = conjadapt.mIdMap;
for(int i=0, j=0; i<displ_conj.size(); i++, j++){
tempMap.put(displ_conj.get(i), (long) j);
}
if(sel_vb!=null){
for(Map.Entry<String, Long> map : tempMap.entrySet()){
if(map.getKey().equals(sel_vb))
conjadapt.ids.add(map.getValue());
}
}
其中 displ_conj 是我存储数据的 ArrayList。mIdMap 存储一个long变量,因为 getItemId() 必须返回一个 long 并且我需要在其他地方做一些事情。