You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GridView中按日期、起止时间定位单元格?(附适配器代码)

解决时间表GridView课程定位问题

Hey there! Let's work through getting those colored course blocks perfectly positioned in your schedule GridView app. Here's a step-by-step approach tailored to your existing code:

1. Expand Your Data Structure

Right now your GridViewItem only holds a title, but we need extra info to map courses to specific cells. Let's create a separate Course class for your schedule entries (or extend your existing item class):

public class Course {
    private String subjectTitle;
    private int dayIndex; // e.g., 0 = Monday, 1 = Tuesday—matches your GridView columns
    private int startRow; // Which row your course starts on (e.g., row 3 = 9:00 AM)
    private int endRow; // Which row your course ends on
    private int color; // Background color for the course block

    // Constructor, getters, and setters
    public Course(String subjectTitle, int dayIndex, int startRow, int endRow, int color) {
        this.subjectTitle = subjectTitle;
        this.dayIndex = dayIndex;
        this.startRow = startRow;
        this.endRow = endRow;
        this.color = color;
    }

    // Getters for all fields
    public String getSubjectTitle() { return subjectTitle; }
    public int getDayIndex() { return dayIndex; }
    public int getStartRow() { return startRow; }
    public int getEndRow() { return endRow; }
    public int getColor() { return color; }
}

Keep your original GridViewItem for base cell content (like time labels on the left or day names at the top), and add a separate list of Course objects to store your schedule data.

2. Update Your Grid Item Layout

Modify gridview_item.xml to support overlaying course blocks on top of the base cell content using a FrameLayout to stack views:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="2dp">

    <!-- Base cell text (time/day labels) -->
    <TextView
        android:id="@+id/item_title"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textSize="12sp"/>

    <!-- Colored course block -->
    <View
        android:id="@+id/course_block"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone"
        android:background="@drawable/course_block_rounded"/>

    <!-- Course title (only visible on the first row of the course) -->
    <TextView
        android:id="@+id/course_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="4dp"
        android:textColor="@android:color/white"
        android:textSize="10sp"
        android:visibility="gone"/>

</FrameLayout>

Create a drawable course_block_rounded.xml for adjustable rounded corners:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="8dp"/>
</shape>

3. Modify the Adapter to Handle Course Positioning

Update your GridviewAdapter to calculate each cell's row/column, then match it to your course data:

public class GridviewAdapter extends BaseAdapter { 
    private ArrayList<GridViewItem> gridCellData; 
    private ArrayList<Course> courseList; // Add this list of courses
    private LayoutInflater layoutInflater;
    private static final int COLUMN_COUNT = 7; // Adjust to your number of days/columns

    public GridviewAdapter(Context context, ArrayList<GridViewItem> gridCellData, ArrayList<Course> courseList){ 
        this.gridCellData = gridCellData; 
        this.courseList = courseList;
        layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

    @Override public int getCount() { return gridCellData.size(); } 
    @Override public Object getItem(int position) { return gridCellData.get(position); } 
    @Override public long getItemId(int position) { return position; } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
        GridViewHolder gridViewHolder; 
        if(convertView == null){ 
            convertView = layoutInflater.inflate(R.layout.gridview_item, parent, false); 
            gridViewHolder = new GridViewHolder(); 
            gridViewHolder.itemTitle = convertView.findViewById(R.id.item_title);
            gridViewHolder.courseBlock = convertView.findViewById(R.id.course_block);
            gridViewHolder.courseTitle = convertView.findViewById(R.id.course_title);
            convertView.setTag(gridViewHolder); 
        } else { 
            gridViewHolder = (GridViewHolder) convertView.getTag(); 
        } 

        // Calculate current cell's row and column
        int currentRow = position / COLUMN_COUNT;
        int currentCol = position % COLUMN_COUNT;

        // Set base cell text (time/day labels)
        gridViewHolder.itemTitle.setText(gridCellData.get(position).getSub_title());

        // Reset course views to hidden by default
        gridViewHolder.courseBlock.setVisibility(View.GONE);
        gridViewHolder.courseTitle.setVisibility(View.GONE);

        // Check if any course should appear in this cell
        for(Course course : courseList){
            if(course.getDayIndex() == currentCol && currentRow >= course.getStartRow() && currentRow <= course.getEndRow()){
                // Show the colored course block
                gridViewHolder.courseBlock.setBackgroundColor(course.getColor());
                gridViewHolder.courseBlock.setVisibility(View.VISIBLE);

                // Only show the course title on the first row of the course
                if(currentRow == course.getStartRow()){
                    gridViewHolder.courseTitle.setText(course.getSubjectTitle());
                    gridViewHolder.courseTitle.setVisibility(View.VISIBLE);
                }

                // Adjust rounded corners to make the course look like a single continuous block
                GradientDrawable bg = (GradientDrawable) gridViewHolder.courseBlock.getBackground();
                float[] cornerRadii = new float[8]; // [top-left, top-right, bottom-right, bottom-left] ×2

                if(currentRow == course.getStartRow()){
                    // Round top corners
                    cornerRadii[0] = 8f;
                    cornerRadii[1] = 8f;
                    cornerRadii[2] = 8f;
                    cornerRadii[3] = 8f;
                }
                if(currentRow == course.getEndRow()){
                    // Round bottom corners
                    cornerRadii[4] = 8f;
                    cornerRadii[5] = 8f;
                    cornerRadii[6] = 8f;
                    cornerRadii[7] = 8f;
                }
                bg.setCornerRadii(cornerRadii);
            }
        }

        return convertView; 
    } 

    static class GridViewHolder{ 
        TextView itemTitle; 
        View courseBlock;
        TextView courseTitle;
    } 
}

4. Map Dates & Times to Rows/Columns

The final step is converting your raw date/time data into dayIndex, startRow, and endRow:

  • Days: Map your date (e.g., "2024-05-20" = Monday) to an index 0-6 (match your GridView's column order).
  • Times: Choose a time slot interval (e.g., 30 minutes per row). Convert start/end times to row numbers (e.g., 8:00 AM = row 0, 8:30 AM = row 1, 9:00 AM = row 2).

Example Mapping Logic:

// Convert a time string like "09:00" to a row index
public int timeToRow(String timeStr){
    String[] parts = timeStr.split(":");
    int hour = Integer.parseInt(parts[0]);
    int minute = Integer.parseInt(parts[1]);
    // Assuming first row is 8:00 AM, each row represents 30 minutes
    return ((hour - 8) * 2) + (minute / 30);
}

This will ensure your courses line up perfectly with the correct GridView cells.

内容的提问来源于stack exchange,提问作者Dyki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:48:09