Android: макет для перекрывающихся событий в календаре - PullRequest
1 голос
/ 26 августа 2011

Я сейчас работаю над приложением календаря. Когда пользователь выбирает дневной вид, ему нужно получить вид, подобный следующему примеру:

http://postimage.org/image/2sboxa22s/

Я не совсем уверен, как это сделать, так как макет должен быть создан во время выполнения, потому что количество событий, их продолжительность, количество перекрытий и т. Д. Является переменным.

Я пытался найти подобные проблемы, но безуспешно.

Мои два цента были бы чем-то вроде использования FrameLayout с LinearLayout для фона (желтый с серыми линиями) и другого FrameLayout поверх того, в который будут помещаться события. Единственная проблема с этим заключается в том, что я не уверен, как правильно расположить места размещения и как понять, как обрабатывать места, где события перекрываются.

UPDATE

Поскольку в Android-фреймворке нет такого понятия, как rowowan (он просто не поддерживается ни одним макетом или виджетом), мне пришлось придумать собственное решение.

В короткие сроки я делаю следующее:

  1. Добавляйте проставки (пустой календарь), пока я не достигну начала первой встречи.
  2. Добавление первой встречи в список, а затем добавление всех встреч, перекрывающих любую встречу в списке.
  3. Когда больше нет перекрывающихся встреч, самое время добавить список в календарь.
  4. Я снова запускаю встречи, чтобы определить, какие могут быть в одном столбце, а какие нет.
  5. Добавьте необходимое количество столбцов, заполняющих пустое пространство между встречами с пустыми макетами.
  6. Повторяйте, пока не добавлены все встречи дня.

Это решение основано на одном: фиксированная минимальная высота. Это означает, что у меня есть минимальный рост, который должен иметь назначение. В моем случае это 60dp. Затем я найду самое короткое назначение, чтобы выяснить фактор, из которого я могу рассчитать рост каждого назначения. Например. если самое короткое назначение через 15 минут, коэффициент будет 4.

Таким образом, встреча в столбце, где короткая встреча составляет 15 минут, 15-минутная встреча будет 60dp, а 1-часовая встреча будет 240dp.

Я не считаю это оптимальным решением, так как оно не на 100% динамично, но оно выполняет свою работу до сих пор.

1 Ответ

2 голосов
/ 29 января 2015

Я глубоко изучил вашу проблему, однако обнаружил, что есть немного проблем с вашим дизайном макета, вы должны генерировать события через класс, который идентифицирует представления и размещает их соответствующим образом, не перекрывая другие события.

http://postimg.org/image/4lqmlnhk7/ (выход для справки)

private int[] Gettimespan(int SHour, int EHour, int SMinutes, int EMinutes, int TotalWidth) {
    // float x = (60 / Minutes) * 100;
    int x = 0; // width for time marking
    int y = 0; // Height For hour marking
    int z = 0; // Margin left for Stime
    int YAxis = 0; // YAxis Adjustment

    int TotalYAxis = 80; // /Total YAxis of Per hour slot
    int HalfOf_TotalYAxis = 40; // /Half of the Total YAxis of Per hour slot
    int MinutesDiff = GetMinutes(SHour, EHour, SMinutes, EMinutes);



    int xAxisFinetuning = 0;
    //Check If any Views Between
    final RelativeLayout rl = (RelativeLayout) _activity.findViewById(R.id.relativeLayout4);
    List<Integer> ViewCount = DetectView(SHour, rl);
    if(ViewCount.size() > 1 && ViewCount != null)
    {
        for(int i = 0; i < ViewCount.size(); i++)
        {
            LinearLayout ll = (LinearLayout) _activity.findViewById(ViewCount.get(i));
            int Stepper = TotalWidth / ViewCount.size();
            xAxisFinetuning += Stepper;
            z  = xAxisFinetuning;
            ll.setMinimumWidth(Stepper - 15);
            ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) ll.getLayoutParams();
            p.leftMargin = z;
            ll.requestLayout();
            x = Stepper - 26;
            //Log.d("LayoutID", "" + ll.getId());
        }
    }

    //Snippet 1: Case Same hour but upper span
    //if(SMinutes >= 0 && EMinutes >= 30 && SMinutes <= 30 && ((SHour+1 == EHour) || (SHour == EHour)))
    if(SMinutes >= 0 && EMinutes >= 30 && SMinutes <= 30 && (SHour == EHour))
    {
        if(x == 0)
        {
            x = TotalWidth;
        }

        if(y == 0)
        {
            if(MinutesDiff > 30)
            {
                y = dpToPx(TotalYAxis); 
            }
            else
            {
                y = dpToPx(HalfOf_TotalYAxis);  
            }
        }
        //if(z == 0)
        //{
        z = 0;
        //}
        if(MinutesDiff >= 30)
        {
            YAxis = 0;  
        }
        else
        {
            YAxis = HalfOf_TotalYAxis;
        }

        return new int[] { x, y - 6, z, YAxis };
    }

    // End Snippet 1.

    //Snippet 2: Case Same hour but lower span
    //if(SMinutes >= 30 && ((SHour+1 == EHour) || (SHour == EHour)))
    if(SMinutes >= 30 && (SHour == EHour))
    {
        if(x == 0)
        {
            x = TotalWidth;
        }

        if(y == 0)
        {
            if(MinutesDiff > 30)
            {
                y = dpToPx(TotalYAxis); 
            }
            else
            {
                y = dpToPx(HalfOf_TotalYAxis);  
            }
        }

        z = 0;

        if(MinutesDiff > 30)
        {
            YAxis = 0;  
        }
        else
        {
            YAxis = HalfOf_TotalYAxis;
        }


        return new int[] { x, y - 6, z, YAxis };
    }

    // End Snippet 2.

    //Snippet 3: Case when Total Hour > 1

    if(SHour != EHour )
    {
        if(x == 0)
        {
        x = TotalWidth;
        }
        if(y == 0)
        {
            Log.d("Calendar Case Next Day", "Ehour " + EHour + " Shour " + SHour);
            if((EHour - SHour)<=1)
            {
            y = dpToPx(((EHour - SHour)+1) * TotalYAxis);
            }
            else
            {
                y = dpToPx(((EHour - SHour)) * TotalYAxis);
            }
        }
        z = 0;
        YAxis = 0;

        return new int[] { x, y - 6, z, YAxis };
    }

    // End Snippet 3.


    return new int[] { x, y - 6, z, YAxis };
    }

private void TimeSpanning(LinearLayout LL, int SHour, int EHour, int SMinutes, int EMinutes, int TotalWidth, TextView Tv) {

    if(SHour > EHour)
    {
        Log.d("Calendar Case Next Day_", "Ehour " + EHour + " Shour " + SHour + " TextView " + Tv.getText());
        EHour = 24;
        //EMinutes = 59;
    }

    int minuteAdjustment = 0;

    if((EHour + ":" + EMinutes).equalsIgnoreCase(SHour + ":" + SMinutes))
    {
        //Log.d("EqualFound","True");
        minuteAdjustment = 59;
    }

    int[] x = Gettimespan(SHour, EHour, SMinutes, EMinutes + minuteAdjustment, TotalWidth);

    //Log.d("Eminute"," - " + EMinutes);

    LL.setMinimumWidth(x[0]);
    LL.setMinimumHeight(x[1]);

    Tv.setWidth(x[0]);
    Tv.setHeight(x[1] - 14);

    int Padding_Top_Bottom = 4;
    int Padding_Left_Right = 4;
    //LL.setPadding(30, 30, 30, 30);
    //tv.setWidth(x[0]);
    //tv.setHeight(x[1]);

    ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) LL.getLayoutParams();
    //ViewGroup.MarginLayoutParams p1 = (ViewGroup.MarginLayoutParams) ll.getLayoutParams();

    switch (SHour) {
    case 0: {
        // 12 am
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(0) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    case 1: {
        // 1 am
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(1) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    case 2: {
        // 2 am
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(2) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    case 3: {
        // 3 am
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(3) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    case 4: {
        // 4 am
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(4) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    case 5: {
        // 5 am
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(5) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    case 6: {
        // 6 am
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(6) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    case 7: {
        // 7 am
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(7) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    case 8: {
        // 8 am
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(8) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    case 9: {
        // 9 am
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(9) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    case 10: {
        // 10 am
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(10) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    case 11: {
        // 11 am
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(11) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    case 12: {
        // 12 pm
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(12) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    case 13: {
        // 1 pm
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(13) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    case 14: {
        // 2 pm
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(14) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    case 15: {
        // 3 pm
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(15) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    case 16: {
        // 4 pm
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(16) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    case 17: {
        // 5 pm
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(17) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    case 18: {
        // 6 pm
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(18) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;

    }

    case 19: {
        // 7 pm
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(19) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    case 20: {
        // 8 pm
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(20) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    case 21: {
        // 9 pm
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(21) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    case 22: {
        // 10 pm
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(22) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }
    case 23: {
        // 11 pm
        p.setMargins(x[2] + Padding_Left_Right, dpToPx(GetCalendarScaleY(23) + x[3]) + Padding_Top_Bottom, Padding_Left_Right, 0);
        LL.requestLayout();
        break;
    }

    }

}

private int dpToPx(int dp) {
    if(_activity != null)
    {
            DisplayMetrics displayMetrics = _activity.getResources().getDisplayMetrics();
            int px = 0;
            if(displayMetrics != null)
            {
                px = Math.round((float) dp * ((float)displayMetrics.densityDpi / (float)DisplayMetrics.DENSITY_DEFAULT));

             return px;
            }
    }
            return 0;
        }

private int GetCalendarScaleY(int Time) {

    //Coordinates of Rows (Y Axis with respect to hours)
    int x = 0;

    switch (Time) {
    case 0: {
        // 12 am
        x = 0;
        break;
    }

    case 1: {
        // 1 am
        x = 80;
        break;
    }

    case 2: {
        // 2 am
        x = 160;
        break;
    }

    case 3: {
        // 3 am
        x = 240;
        break;
    }

    case 4: {
        // 4 am
        x = 320;
        break;
    }

    case 5: {
        // 5 am
        x = 400;
        break;
    }

    case 6: {
        // 6 am
        x = 480;
        break;
    }

    case 7: {
        // 7 am
        x = 560;
        break;
    }

    case 8: {
        // 8 am
        x = 640;
        break;
    }

    case 9: {
        // 9 am
        x = 720;
        break;
    }

    case 10: {
        // 10 am
        x = 800;
        break;
    }

    case 11: {
        // 11 am
        x = 880;
        break;
    }

    case 12: {
        // 12 pm
        x = 960;
        break;
    }

    case 13: {
        // 1 pm
        x = 1040;
        break;
    }

    case 14: {
        // 2 pm
        x = 1120;
        break;
    }

    case 15: {
        // 3 pm
        x = 1200;
        break;
    }

    case 16: {
        // 4 pm
        x = 1280;
        break;
    }

    case 17: {
        // 5 pm
        x = 1360;
        break;
    }

    case 18: {
        // 6 pm
        x = 1440;
        break;
    }

    case 19: {
        // 7 pm
        x = 1520;
        break;
    }

    case 20: {
        // 8 pm
        x = 1600;
        break;
    }

    case 21: {
        // 9 pm
        x = 1680;
        break;
    }

    case 22: {
        // 10 pm
        x = 1760;
        break;
    }
    case 23: {
        // 11 pm
        x = 1840;
        break;
    }

    }

    return x;
}
...