【问题标题】:Dynamic display of ListView elements partially workingListView 元素的动态显示部分工作
【发布时间】:2010-07-26 20:21:28
【问题描述】:

我正在制作一个时间表程序,用户可以在其中输入他的出拳和出拳。我有一个从日历对象数组填充的 ListView。我希望每一行都显示日期和日期,然后在新的一行显示时间,但我只想显示与前一个元素不同的日期和日期。

目前,我根据使用 position 与 position-1 的比较(用作数组的索引)在 BaseAdapter 中设置可见性。这仅在整个列表适合屏幕时才有效。如果它超出屏幕并且用户滚动,结果是不可预测的。

为了进一步混淆,我根据位置设置时间的颜色,在绿色和红色(输入/输出)之间交替,它可以按预期工作,滚动与否。

Android 如何在滚动时处理 ListView 位置,或者我可以采取哪些不同的方式来显示/隐藏日期和日期?

public class TimeSheetActivity extends Activity {
SQLiteDatabase timesDatabase;
Cursor punchCursor;

private static Calendar[] allPunches;



@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.timesheet);
} //end onCreate()


@Override
public void onResume() {
    super.onResume();
    //Open database
    timesDatabase = openOrCreateDatabase(
            "times_database.db",
            SQLiteDatabase.CREATE_IF_NECESSARY,
            null);
    timesDatabase.setLocale(Locale.getDefault());
    timesDatabase.setLockingEnabled(true);
    timesDatabase.setVersion(1);
    punchCursor = timesDatabase.query("Timepunches", null, null, null, null, null, "punch ASC;");
    updateTimeSheet();
} //end onResume()


@Override
public void onPause() {
    super.onPause();
    timesDatabase.close();
} //end onResume()


private static class  EfficientAdapter extends BaseAdapter {
    private LayoutInflater mInflater;

    public EfficientAdapter(Context context) {
        mInflater = LayoutInflater.from(context);
    }

    public int getCount() {
        return allPunches.length;
    }

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.time_list_row, null);
            holder = new ViewHolder();
            holder.text1 = (TextView) convertView.findViewById(R.id.day_textview);
            holder.text2 = (TextView) convertView.findViewById(R.id.date_textview);
            holder.text3 = (TextView) convertView.findViewById(R.id.times_this_day_textview);

            convertView.setTag(holder);
        }
        else {
            holder = (ViewHolder) convertView.getTag();
        }

        String dayNames[] = new DateFormatSymbols().getWeekdays();

        //Initialize first list element
        if (position < 1) {
            holder.text1.setText(dayNames[allPunches[position].get(Calendar.DAY_OF_WEEK)]);
            holder.text2.setText(formatDate(allPunches[position]));

        }
        else {
            holder.text1.setText(dayNames[allPunches[position].get(Calendar.DAY_OF_WEEK)]);
            holder.text2.setText(formatDate(allPunches[position]));
            holder.text1.setVisibility(View.VISIBLE);
            holder.text2.setVisibility(View.VISIBLE);

            //Hide day and date if same as last
            if (formatDate(allPunches[position]).contentEquals(formatDate(allPunches[position-1]))) {
                holder.text1.setVisibility(View.GONE);
                holder.text2.setVisibility(View.GONE);
            }
        }

        holder.text3.setText(formatTime(allPunches[position], true) + " " + position);

        //Color in/out punches
        if (position%2 == 0) {
            holder.text3.setTextColor(Color.GREEN);
        }
        else {
            holder.text3.setTextColor(Color.RED);
        }

        return convertView;
    } //end getView()

    static class ViewHolder {
        public TextView text1;
        TextView text2;
        TextView text3;
    }
} //end EfficientAdapter


public void updateTimeSheet() {
    punchCursor = timesDatabase.query("Timepunches", null, null, null, null, null, "punch ASC;");
    allPunches = new Calendar[punchCursor.getCount()];

    int i = 0;                  //for indexing allPunches
    Calendar nextDay = Calendar.getInstance();
    nextDay.setLenient(true);

    //populate allPunches
    for (punchCursor.moveToFirst(); !punchCursor.isAfterLast(); punchCursor.moveToNext()) {
        allPunches[i] = Calendar.getInstance();
        allPunches[i].setTimeInMillis(punchCursor.getLong(0));
        ++i;
    } //end for

    final ListView timeSheetListView = (ListView)findViewById(R.id.timesheet_listview);
    timeSheetListView.setAdapter(new EfficientAdapter(this));
    timeSheetListView.setOnItemClickListener(new OnItemClickListener() {...}); //end click listener for list item
} //end updateTimeSheet()


public static String formatTime(Calendar thisTime, boolean showAMPM) {...}


public static String formatDate(Calendar thisDate) {
    String formattedDate = "";
    formattedDate += thisDate.get(Calendar.MONTH) +"-"+ thisDate.get(Calendar.DAY_OF_MONTH) +"-"+ thisDate.get(Calendar.YEAR);
    return formattedDate;
} //end formatDate()

} //结束时间表活动

【问题讨论】:

    标签: java android listview


    【解决方案1】:

    ListView 中的视图会在您滚动时重新使用。这可能会导致您看到的奇怪行为。重写 getView 时要记住的重要一点是每次都明确设置行为。不要依赖处于默认状态的视图,因为您可能正在重用已更改的视图。

    在您的特定情况下,请确保始终将可见性明确设置为 true 或消失。

    另外,您是否直接复制粘贴此代码?我相信您的第二个 else 语句缺少右括号。

    【讨论】:

    • 我在 getView() 中明确将视图设置为 VISIBLE 和 GONE。我知道这些观点被重用了(虽然谢谢),但我认为还有其他事情发生。我做了复制和粘贴,但我删除了不相关的代码。我的代码中存在此处缺少的括号。谢谢你的收获。
    • 我看不出你在做什么有任何明显的错误。您能否进一步解释不可预测的行为是什么?
    • 我可能已经修好了。谢谢你的帮助,梅拉。
    【解决方案2】:

    我似乎一直在错误的地方设置 VISIBLE。这是似乎已修复的 getView() 代码!

        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.time_list_row, null);
                holder = new ViewHolder();
                holder.text1 = (TextView) convertView.findViewById(R.id.day_textview);
                holder.text2 = (TextView) convertView.findViewById(R.id.date_textview);
                holder.text3 = (TextView) convertView.findViewById(R.id.times_this_day_textview);
    
                convertView.setTag(holder);
            }
            else {
                holder = (ViewHolder) convertView.getTag();
            }
    
            String dayNames[] = new DateFormatSymbols().getWeekdays();
            holder.text1.setVisibility(View.VISIBLE);
            holder.text2.setVisibility(View.VISIBLE);
    
            //Initialize list
            if (position < 1) {
                holder.text1.setText(dayNames[allPunches[position].get(Calendar.DAY_OF_WEEK)]);
                holder.text2.setText(formatDate(allPunches[position]));
            }
            else {
                //Show day and date if not same as last
                holder.text1.setText(dayNames[allPunches[position].get(Calendar.DAY_OF_WEEK)]);
                holder.text2.setText(formatDate(allPunches[position]));
    
                if (formatDate(allPunches[position]).contentEquals(formatDate(allPunches[position-1]))) {
                    holder.text1.setVisibility(View.GONE);
                    holder.text2.setVisibility(View.GONE);
                }
            }
    
            holder.text3.setText(formatTime(allPunches[position], true));
    
            //Color in/out punches
            if (position%2 == 0) {
                holder.text3.setTextColor(Color.GREEN);
            }
            else {
                holder.text3.setTextColor(Color.RED);
            }
    
            return convertView;
        } //end getView()
    
        static class ViewHolder {
            public TextView text1;
            TextView text2;
            TextView text3;
        }
    } //end EfficientAdapter
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-18
      • 1970-01-01
      相关资源
      最近更新 更多