2

iPhoneのようにタイムラインを作りたい

ここに画像の説明を入力してください

イベント時間は9.42にすることができ、9.30からの距離の%で9.30の破線の下に描画を開始する必要があります。

私が考えることができる唯一の方法は、タイムラインを使用ScrollViewしてプログラムで追加することです。FrameLayout

<ScrollView
        android:id="@+id/scrollView1"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >

        <FrameLayout
            android:id="@+id/timeline"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

        </FrameLayout>
    </ScrollView> 

ListView代わりに使用できればもっと良いScrollViewかもしれませんが、イベントが10.50から始まるため、セル全体にイベントを自由に配置する方法がわかりません。

このイベントを説明するテキストは、セルを通過する必要があります。

誰かが私を提案できますか?ありがとう。

4

1 に答える 1

2

最近同じ問題にぶつかった。フレームレイアウトのアイデアから始めましたが、その上にたくさんのビューがありますが、アイテムの下のグリッドなどを描画してカスタマイズするために必要なパフォーマンスと作業量にはあまり満足していませんでした。

したがって、私が先に進めて統合したソリューションは、クラスを拡張し、そのメソッドと関連するメソッドをViewオーバーライドして、必要なものをすべて描画することでした。onDraw

この場合、何が起こっているのか、どのように見せたいのかを非常に細かく制御できます。言うまでもなく、基になるグリッドをビットマップにキャッシュするなど、パフォーマンスの向上を実装できました。これは、レイアウトやビューの構成のような高レベルのものを操作する場合に実現するのは非常に困難です。

いずれにせよ、あなた、または同じ問題を抱えている人は、次のような単純なものから始めたいと思うかもしれません(コードは私の頭のてっぺんから外れています):

public class MyDayTimeline extends View {
    String [] timeMarkers; // time strings, like "9.00 AM" or something
    Rect [] eventRects; // a bunch of rectangles, which correspond to your events
    final int rowCount;
    final int rowHeightPx;
    final int firstColumnWidthPx;

    // ..... constructors, size and painting initialization, event position calculation and whatnot

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawLine(firstColumnWidthPx, 0, firstColumnWidthPx, getMeasuredHeight(), delimeterLinesPaint); // draw a delimeter between time markers and the rest of the control space

        for (int i = 1; i < rowCount; i++) {
            canvas.drawLine(0, i * rowHeightPx, getMeasuredWidth(), i * rowHeightPx, delimeterLinesPaint); // draw a bunch of lines separating each hour
        }

        for(int i = 0; i < eventRects.size(); i++) { // draw a bunch rectangles, each representing an event
            canvas.drawRect(eventRects[i], eventPaintBackgroundPaint);
            canvas.drawRect(eventRects[i], eventPaintBorderPaint);
        }
    }
}

一見、実行する必要のある作業の量は非常に圧倒的であるように見えますが、最初に実行する必要があることを計画してから実行する場合、実際にはそうではありません。私はこのようなもので行きました:

  1. onDraw()すべてのサイズと色をハードコーディングして、オーバーライドで単純なタイムライングリッドを描画することから始めます。
  2. オーバーライドonMeasure()してonSizeChanged()、それに応じてサイズ制御フィールドの変更を開始します。24 * rowHeightPxメジャーの仕様に関係なく、使用可能なすべてのスペースを幅方向に配置し、高さ方向に大胆に要求する場所を決定する単純なサイズを使用しました。
  3. 'canvas.drawText()'を使用して、タイムグリッドに一連のタイムマイルストーンを配置します。
  4. イベントを定義するための構造を考え出します。開始日時と終了日時、件名の文字列、長方形の配列を使用しました。コントロールのサイズが変更された場合、各イベントが取る必要のある長方形を再計算します。
  5. onDraw()以前に定義した構造と位置の計算を適切に行うことで、イベント描画を実装します。
  6. 数日間にわたるイベントなど、特定のケースを処理します。
  7. onTouchEvent()何かでタップの処理を開始します。いくつかのログを追加して、ヒットテストが正しく実行されているかどうかを確認し、必要に応じて、強調表示された色でイベントフレームの再描画を開始します。
  8. 再利用性の観点から、コントロールを改善します。一部のプロパティのゲッターとセッターを定義し、でカスタム属性を定義attrs.xmlし、初期化コードでそれらの処理を実装します。EventClickedListenerなどのカスタムリスナーを公開します。
  9. その上にいくつかのサポートコントロールを追加します。全体をで包み、水平方向のスワイプを処理し、前/翌日/週/月を表示するためScrollViewに行きました。ViewPager
  10. ほぼ準備が整った日のタイムラインが与えられたら、そこから基本クラスを抽出し、週や月のタイムラインなどの他のタイムラインで作業を開始します。

そして、あなたとあなたのチームメートが結果に満足するまで、あなたのコントロールを改善し続けてください。もちろん、各ステップでコントロールを常にテスト、デバッグ、修正する必要があるため、多数のテストケースを用意しておくと非常に役立ちます。

また、週と月の概要を扱っていたときに、標準のCalendar APIを使用する際に問題が発生したため、Joda Timeなどの他のライブラリの使用を検討することもできますが、それは別の話です。

于 2013-08-23T10:45:15.430 に答える