22

GridViewベースのカレンダーの作成に問題があります。グリッドは次のとおりです。

GridViewカレンダー

これはイベントが入力されたカレンダーであると想定されているため、アダプターにOnClickListenerを実装させ、カレンダーのすべてのボタンにそのリスナーを設定します。最初のボタン(この場合は番号30)を除いて、すべてのボタンで完全に機能します。クリックしても機能しませんが、最初のボタンをクリックしようとした後に別のボタンをクリックすると、他のボタンのクリックを実行する直前に、最初のボタンのクリックが実行されます。

関連する質問を約10ページスキャンしましたが、この問題を抱えている人は見つかりませんでした。助けてください!

尋ねられたように、これが私のコードのgetView関数です:

    public View getView(int position, View convertView, ViewGroup parent)
    {
        View row = convertView;
        ViewHolder holder;
        if (row == null)
        {
            holder = new ViewHolder();
            LayoutInflater inflater = (LayoutInflater) _context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.calendar_day_gridcell, parent, false);
            holder.gridCell = (Button) row.findViewById(R.id.calendar_day_gridcell);
            holder.multiDayEvent = (EventLengthView)row.findViewById(R.id.eventLengthView);
        }
        else{
            holder = (ViewHolder)row.getTag();
        }

        int calendarGridHeight = (calendarView.getHeight()-5)/(getCount()/7);
        AbsListView.LayoutParams params = new AbsListView.LayoutParams(
                android.view.ViewGroup.LayoutParams.FILL_PARENT,
                calendarGridHeight);
        row.setLayoutParams(params);

        //Change the background drawable depending on the position in the calendar
        if ((position+1) % 7 == 0){
            holder.gridCell.setBackgroundDrawable(getResources().getDrawable(R.drawable.calendar_button_selector_end_row));
        }
        if (getCount() - position < 8){
            holder.gridCell.setBackgroundDrawable(getResources().getDrawable(R.drawable.calendar_button_selector_end_column));
        }
        if (position == getCount()-1){
            holder.gridCell.setBackgroundDrawable(getResources().getDrawable(R.drawable.calendar_button_selector_end));
        }
        holder.gridCell.setOnClickListener(this);

        holder.gridCell.setTag(null);//clear tags

        // ACCOUNT FOR SPACING
        String[] day_color = list.get(position).split("-");
        int theday = Integer.parseInt(day_color[0]);
        int themonth = Integer.parseInt(day_color[2]);
        int theyear = Integer.parseInt(day_color[3]);
        String date = DateFormat.format("dd/M/yy", new Date(theyear,themonth,theday)).toString();
        if ((!eventsMap.isEmpty()) && (eventsMap != null))
        {
            if (eventsMap.containsKey(date))
            {
                holder.multiDayEvent.SetMeasure(calendarView.getWidth()/7, calendarGridHeight);

                holder.multiDayEvent.setVisibility(View.VISIBLE);
                //holder.singleDayEvent.setVisibility(View.VISIBLE);
                Event event = (Event) eventsMap.get(date);
                holder.multiDayEvent.AddEvent(event);
                holder.gridCell.setTag(event);
            }
            else{
                //holder.singleDayEvent.setVisibility(View.GONE);
                holder.multiDayEvent.setVisibility(View.GONE);
            }
        }

        // Set the Day GridCell
        holder.gridCell.setText(Integer.toString(theday));

        if (day_color[1].equals("GREY"))
        {
            holder.gridCell.setTextColor(Color.GRAY);
        }
        if (day_color[1].equals("WHITE"))
        {
            holder.gridCell.setTextColor(Color.WHITE);
        }
        if (day_color[1].equals("BLUE"))
        {
            holder.gridCell.setTextColor(Color.BLUE);
        }

        row.setTag(holder);
        return row;
    }

    public class ViewHolder{
        Button gridCell;
        ImageView singleDayEvent;
        EventLengthView multiDayEvent;
    }

    public void onClick(View view)
    {
        if (view.getTag() != null){
            Event event = (Event)view.getTag();

            eventListView.setAdapter(new EventListAdapter(CalendarScreen.this, event));
            eventListViewLayout.setVisibility(View.VISIBLE);
            eventListViewLayout.startAnimation(fadeIn);
        }
        else if (eventListViewLayout.getVisibility() == View.VISIBLE){
            onBackPressed();
        }
    }

onClickは、左上隅の最初のグリッドセルを除くすべてのグリッドセルに対して呼び出されます

4

7 に答える 7

15

私は同じ問題を抱えていました。 setLayoutParams を if(view == null) 句内に保持するとうまくいきました。そのようにビューのリサイクルを犠牲にする必要はありません。

お気に入り :

 if(row == null){
   // inflate row
   row.setLayoutParams(params);
   //remaining code
 }else{
    holder = (ViewHolder)row.getTag();
 }
 // everything else

なぜそれが機能するのかわかりませんが、私にとってはうまくいきました。また、stackoverflow の同じ問題に関するすべてのコードで、if 句の外で setLayoutParams も使用されていることに気付きました。これは初めてなので、どこにでも投稿できるかどうかわかりません。それが役に立てば幸いです。

ソース: 多くの試行錯誤。

于 2014-03-24T13:23:12.113 に答える
8

わかりました、私は解決策を見つけました。問題は次の行でした。

ViewHolder holder;
if (convertView == null)
{
    holder = new ViewHolder();
    LayoutInflater inflater = (LayoutInflater) _context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    convertView = inflater.inflate(R.layout.calendar_day_gridcell, parent, false);
    holder.gridCell = (Button) convertView.findViewById(R.id.calendar_day_gridcell_button);
    holder.multiDayEvent = (EventLengthView) convertView.findViewById(R.id.eventLengthView);
    convertView.setTag(holder);
}
else {
    holder = (ViewHolder) convertView.getTag();
}

そこに gridCell ボタンを配置すると、どういうわけか、アダプターの最初の位置のクリック リスナーが混同されます。タグで取得するのではなく、すべてのパスでホルダーを開始するだけで修正しました(パフォーマンスには優れていますが、まあまあです)。助けてくれてありがとう。

于 2012-08-08T15:11:51.643 に答える
1

これと同じ問題がありました。最初のアイテムのクリック イベントが大幅に遅れました。私はすでにnotifyDataSetInvalidated()を使用していました。 onItemClickListener() を使用すると問題が解決しましたが、個々のアイテムの onClick リスナーがこの動作をする理由はまだわかりません。

于 2014-02-08T16:49:54.910 に答える
1

価値があるのは、この問題もありました(グリッドビューの最初のセルが onclick を遅らせた)ことです。

私の場合、(軽くカスタマイズされた) グリッドビューを使用して、動的なイメージビューのセットを表示/非表示にし、グリッドビューを再描画しました。事前に準備され、アダプターに保存されているすべてのイメージビュー。

最初に、アダプターで notifyDataSetChanged() を使用しましたが、これにより、セットが更新されるたびに最初のセルのクリックが遅れるという問題が発生しました。グリッドビューを無効にするだけに変更しましたが、今は問題ありません。私のすべてのビューはすでに作成され、アダプターに保存されていることに注意してください。実際に表示されているビューを確認するのは getview メソッドだけです。

于 2013-12-04T16:49:03.620 に答える
0

各ボタンに onClickListeners を設定する代わりに、GridView オブジェクトに onItemClickListener を設定します。

そして、ここであなたの問題に関する別の質問を見つけました。バウンティかな?

于 2012-08-02T13:29:11.863 に答える