[Android Code] การสร้าง Android Slices ตอนที่ 2
สวัสดีครับ บทความนี้มาเขียนต่อเรื่อง slice ที่ยังลองเล่นไม่เสร็จ มีอีกนิดหน่อย
ตอนก่อนหน้านี้
การทำ 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); } }
ลองรันดูผลลัพธ์
ดังนั้นคราวนี้เราจะทำกี่ 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(); } }
ลองรัน
Mode ของ Slice View
ตัว SliceView สามารถกำหนด mode ได้ 3 แบบ คืิอ SHORTCUT , SMALL , LARGE
MODE_LARGE คือเห็นทั้งหมด
MODE_SMALL คือเห็นแค่ส่วน Header
MODE_SHORTCUT คือ แสดงแค่ icons
คำอธิบายใน 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");
กรณีที่เป็น 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 คือไม่ได้กำหนด