web analytics

[Android Code] การสร้าง Android Slices ตอนที่ 2

cover-2

สวัสดีครับ บทความนี้มาเขียนต่อเรื่อง slice ที่ยังลองเล่นไม่เสร็จ มีอีกนิดหน่อย

ตอนก่อนหน้านี้

[Android Code] การสร้าง Android Slices ตอนที่ 1

การทำ Multi-Slice

แอปของเราสามารถมีหลาย slice ได้ และสามารถทำได้หลายวิธี วิธีที่ผมใช้คือ 1 Provider ต่อ 1 เรื่อง เช่น Provider นี้จะมี slice ต่างๆเกี่ยวกับการปรับเสียง จะไม่ใช่ 1 provider ต่อ 1 slice
แล้วก็นำโค้ดส่วนการสร้าง slice ไปแยกเป็นคลาส Manager ของใครของมันอีกที

public class MySlicesProvider extends SliceProvider {

    @Override
    public boolean onCreateSliceProvider() {
        return true;
    }

    public Slice onBindSlice(Uri sliceUri) {
        switch (sliceUri.getPath()) {
            case "/volume":
                return MyVolumeSliceManager.createVolumeSlice(getContext(), sliceUri);
            case "/slide":
                return MyVolumeBarSliceManager.createVolumeBarSlice(getContext(), sliceUri);
        }
        return null;
    }

}

 

ที่เหลือก็แล้วแต่เราจะปรับแต่ง slice แล้วละ เช่นการทำ InputRange หรือปกติเราจะเรียกว่า Slider

public class MyVolumeBarSliceManager {
    ...
    public static Slice createVolumeBarSlice(Context context, Uri sliceUri) {
        // Construct our parent builder
        ListBuilder listBuilder = new ListBuilder(context, sliceUri, ListBuilder.INFINITY);

        // Add the row to the parent builder
        listBuilder.addRow(new ListBuilder.RowBuilder()
                .setTitle("Volume = " + MyData.volume)
                .setPrimaryAction(getSliceActionOpenActivity(context)));

        ListBuilder.InputRangeBuilder inputRangeBuilder = new ListBuilder.InputRangeBuilder();
        listBuilder.addInputRange(inputRangeBuilder // Create the input row.
                .setInputAction(createPendingIntentWithData(context,MySliceBroadcastReceiver.REQ_CODE_UPDATE_VOLUME,inputRangeBuilder.getValue()))
                .setMax(100)
                .setValue(MyData.volume)
        );

        // Build the slice
        return listBuilder.build();
    }
}

 

ไปที่แอปตัวที่สองสำหรับ slice view ก็เพิ่ม SliceView อีกตัวลงใน layout

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical"
    android:padding="16dp">

    <androidx.slice.widget.SliceView
        android:id="@+id/sliceView_1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <androidx.slice.widget.SliceView
        android:id="@+id/sliceView_2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

 

ปรับโค้ดใน activity ให้รองรับ sliceView อีกตัว

public class MainActivity extends AppCompatActivity {

    private SliceView sliceView1;
    private SliceView sliceView2;

    @SuppressLint("RestrictedApi")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        sliceView1 = findViewById(R.id.sliceView_1);
        sliceView2 = findViewById(R.id.sliceView_2);

        initSlice(sliceView1,SliceView.MODE_LARGE,"content://com.benzneststudios.myandroidslice/volume");
        initSlice(sliceView2,SliceView.MODE_LARGE,"content://com.benzneststudios.myandroidslice/slide");
    }

    private void initSlice(SliceView sv,int mode,String strURI) {
        sv.setMode(mode);
        LiveData liveData = SliceLiveData.fromUri(this, Uri.parse(strURI));
        liveData.observe(this, sv);
    }
}

 

ลองรันดูผลลัพธ์

screenshot_1534820888

ดังนั้นคราวนี้เราจะทำกี่ slice ก็ได้แล้ว

 

การใช้ Grid

เราสามารถทำตารางลงใน slice ได้ เรียกว่า Grid Row-Cell มันก็คือการสร้างแถว แล้วก็สร้างคอลัมนั่นแหละ
.addGridRow() คือเพิ่มแถว
.addCell() คือเพิ่มคอลัมน์

แล้วใน cell ก็เพิ่มรูป เพิ่มหัวข้อได้

public class MyFruitGridCellManager {
    ...
    public static Slice createFruitSlice(Context context, Uri sliceUri) {
        ListBuilder listBuilder = new ListBuilder(context, sliceUri, ListBuilder.INFINITY)
                .setHeader(
                        // Create the header.
                        new ListBuilder.HeaderBuilder()
                                .setTitle("Fruit")
                                .setPrimaryAction(getSliceActionOpenActivity(context))
                )
                // Add a grid row to the list.
                .addGridRow(new GridRowBuilder()
                        // Add cells to the grid row.
                        .addCell(new GridRowBuilder.CellBuilder()
                                .addImage(IconCompat.createWithResource(context,R.drawable.ic_banana), ListBuilder.LARGE_IMAGE)
                                .addTitleText("Banana")
                                .addText("$0.99")
                                .setContentIntent(createPendingIntentWithData(context,1,0))
                        ).addCell(new GridRowBuilder.CellBuilder()
                                .addImage(IconCompat.createWithResource(context,R.drawable.ic_citrus), ListBuilder.LARGE_IMAGE)
                                .addTitleText("Citrus")
                                .addText("$1.99")
                                .setContentIntent(createPendingIntentWithData(context,1,0))
                        )
                        .addCell(new GridRowBuilder.CellBuilder()
                                .addImage(IconCompat.createWithResource(context,R.drawable.ic_pear), ListBuilder.LARGE_IMAGE)
                                .addTitleText("Pear")
                                .addText("$1.99")
                                .setContentIntent(createPendingIntentWithData(context,1,0)))
                        .addCell(new GridRowBuilder.CellBuilder()
                                .addImage(IconCompat.createWithResource(context,R.drawable.ic_durian), ListBuilder.LARGE_IMAGE)
                                .addTitleText("Durian")
                                .addText("$3.99")
                                .setContentIntent(createPendingIntentWithData(context,1,0)))
                        // Every slice needs a primary action.
                        .setPrimaryAction(getSliceActionOpenActivity(context))
                );
        return listBuilder.build();
    }
}

 

ลองรัน

screenshot_1534823710

 

Mode ของ Slice View

ตัว SliceView สามารถกำหนด mode ได้ 3 แบบ คืิอ SHORTCUT , SMALL , LARGE
MODE_LARGE คือเห็นทั้งหมด
MODE_SMALL คือเห็นแค่ส่วน Header
MODE_SHORTCUT คือ แสดงแค่ icons

screenshot_15348237101

 

คำอธิบายใน library

    /**
     * Mode indicating this slice should be presented in small format, only top-level information
     * and actions from the slice are shown.
     */
    public static final int MODE_SMALL       = 1;
    /**
     * Mode indicating this slice should be presented in large format, as much or all of the slice
     * contents are shown.
     */
    public static final int MODE_LARGE       = 2;
    /**
     * Mode indicating this slice should be presented as a tappable icon.
     */
    public static final int MODE_SHORTCUT    = 3;

 

ทีนี้มาลองเล่นดู ว่าแต่ละ mode จะเป็นยังไง

        initSlice(sliceView1,SliceView.MODE_LARGE,"content://com.benzneststudios.myandroidslice/fruit");
        initSlice(sliceView2,SliceView.MODE_SMALL,"content://com.benzneststudios.myandroidslice/fruit");
        initSlice(sliceView3,SliceView.MODE_SHORTCUT,"content://com.benzneststudios.myandroidslice/fruit");

2

กรณีที่เป็น MODE_SHORTCUT แต่ slice ไม่มี icons จะแสดงเป็นไอคอนแอปแทน

 

Mode ของ Image ใน Slice

ใน builder ของ slice นั้นจะมี IMAGE แล้วเราก็สามารถกำหนด mode ได้ ซึ่งจะมีอยู่ 4 mode
คือ ICON , SMALL , LARGE , UNKNOWN

ผมจะลองเปลี่ยน Fruit Grid ของผมเป็นโหมดต่างๆ

                        // Add cells to the grid row.
                        .addCell(new GridRowBuilder.CellBuilder()
                                .addImage(IconCompat.createWithResource(context,R.drawable.ic_banana), ListBuilder.ICON_IMAGE)
                                .addTitleText("Banana")
                                .addText("$0.99")
                                .setContentIntent(createPendingIntentWithData(context,1,0)))
                        .addCell(new GridRowBuilder.CellBuilder()
                                .addImage(IconCompat.createWithResource(context,R.drawable.ic_citrus), ListBuilder.SMALL_IMAGE)
                                .addTitleText("Citrus")
                                .addText("$1.99")
                                .setContentIntent(createPendingIntentWithData(context,1,0)))
                        .addCell(new GridRowBuilder.CellBuilder()
                                .addImage(IconCompat.createWithResource(context,R.drawable.ic_pear), ListBuilder.LARGE_IMAGE)
                                .addTitleText("Pear")
                                .addText("$1.99")
                                .setContentIntent(createPendingIntentWithData(context,1,0)))
                        .addCell(new GridRowBuilder.CellBuilder()
                                .addImage(IconCompat.createWithResource(context,R.drawable.ic_durian), ListBuilder.UNKNOWN_IMAGE)
                                .addTitleText("Durian")
                                .addText("$3.99")
                                .setContentIntent(createPendingIntentWithData(context,1,0)))

 

จะเห็นว่าโหมด ICON คือมันจะทำ tint ให้รูปเราเป็นสีขาวแล้วพื้นหลังเป็น accent color
SMALL คือไอคอนเป็นสีขนาดเล็ก ส่วน LARGE ก็ใหญ่
UNKNOWN คือไม่ได้กำหนด

screenshot_1534825161