Androidで動画広告用ライブラリーを作ってみたい(動画の一覧表示)

Androidで動画広告用ライブラリーを作ってみたい(動画の一覧表示)

お久しぶりです。本間です。
Androidで動画広告用のライブラリーを作ってみたい(動画ダウンロード)に引き続き動画広告用のライブラリーについて書いていこうと思います。

  1. 動画のダウンロード <- Done
  2. 動画の一覧表示 <- 今回はこれについて
  3. 動画の再生

前回は動画のダウンロードについて書いたので、今回はダウンロードした動画の一覧を表示出来るようにしたいと思います。


※ 画像はイメージです

動画の一覧表示

Androidで複数のデータを一覧表示する時にはAndroid 1.0(API Level 1)から使用できるListViewを使います。Android 5.0(API Level 21)からListViewよりレイアウトやアニメーションを自由にカスタマイズすることの出来るRecycleViewが追加されました。自由度が高い分自分で面倒を見なければならないことがListViewより多いようなので今回は安心安全のListViewを使っていきます。

ListViewを使って複数のデータを一覧表示するには

ListViewを使って複数のデータを一覧表示するには下記の要素が必要です。

src

  • ListViewActivity(Fragment).java
  • ArrayAdapter.java
  • Item.java

res

  • item_layout.xml
  • list_view_layout.xml

ListViewActivity(Fragment).java
 ダウンロードした動画の一覧を取得してListViewに表示するコントローラ
ArrayAdapter.java
 Itemをviewに当てはめるアダプター
Item.java
 ListViewに表示させる1つ1つのアイテム
item.xml
 ListViewに表示させるアイテム1つ1つのレイアウト
list_view.xml
 ListViewを含む全体のレイアウト

この構成はListViewを使う時によくある構成ですが、今回ライブラリ(jar)にすることを想定しているのでresが使えません。。。

jarにはresを含めることが出来ない

Androidではプロジェクトに組み込んだリソースをプログラムから利用するために、各リソースにリソースIDが割り当てられます。リソースIDはビルド時に自動で作成されるR.javaで管理されています。
そのためライブラリをjarで配布する場合、resを組み込んで配布することは困難なようです。Library Projectとして配布する場合はresを含めることは可能ですが、編集可能なソースを配布することなるので不正に繋がる可能性がでてきます。そのためresを組み込む事は出来ませんがjarで配布する事を想定して作成していきます。

res以下に作成したlayout.xmlをjavaに書き換える

srcの構成については省略します。
まず、ListViewを含む全体のレイアウトlist_view.xmlをjavaに書き換えます。

list_view.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">

<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</LinearLayout>

上記のxmlをjavaで書き換えるのはそこまで難しくないですね。
javaに書き換えたものが下記になります。

public class ListViewLayout extends LinearLayout {
public ListView listView;
public ListViewLayout(Context context) {
super(context);
init(context);
}
private void init(Context context) {
listView = new ListView(context);
LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT
);
this.setLayoutParams(matchParent);
this.setOrientation(LinearLayout.HORIZONTAL);
this.addView(listView, matchParent);
}
}

続いてListViewに表示する一つ一つのアイテムのレイアウトitem.xmlをjavaに書き換えます。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@+color/light_gray" >

<RelativeLayout
android:layout_width="120dp"
android:layout_height="90dp" >

<ImageView
android:layout_width="120dp"
android:layout_height="90dp"
android:layout_centerInParent="true"
android:background="@+color/black />
<TextView
android:layout_width="
wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="2dp"
android:layout_marginRight="2dp"
android:background="@+color/trans_7_black"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:textColor="@+color/white"
android:textSize="10sp" />

</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@+color/white"
android:orientation="vertical"
android:paddingBottom="5dp"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:paddingTop="5dp" >

<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:textColor="@+color/black"
android:textSize="15sp"
android:maxLines="3"
android:ellipsize="end"
android:paddingBottom="5dp"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:paddingTop="5dp" />

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@+color/gray"
android:textSize="12sp"
android:gravity="right"
android:paddingBottom="5dp"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:paddingTop="5dp" />

</LinearLayout>
</LinearLayout>

上記のxmlをjavaに書き換えるのは・・・
結構大変ですね。。。

public class ItemLayout extends LinearLayout {
public ImageView thumbnailView;
public TextView durationView;
public TextView titleView;
public TextView rewardView;
public VideoInfoItemLayout(Context context) {
super(context);
init(context);
}

private void init(Context context) {
RelativeLayout thumbnailLayout = createThumbnailLayout(context);
LinearLayout infoLayout = createInfoLayout(context);
AbsListView.LayoutParams thumbnailLayoutParams = new AbsListView.LayoutParams(
dp2px(Constant.THUMBNAIL_WIDTH_DP), dp2px(Constant.THUMBNAIL_HEIGHT_DP)
);
AbsListView.LayoutParams infoLayoutParams = new AbsListView.LayoutParams(
AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.MATCH_PARENT
);
this.setOrientation(HORIZONTAL);
this.setBackgroundColor(Constant.VIDEO_INFO_ITEM_BACKGROUND_COLOR);
this.addView(thumbnailLayout, thumbnailLayoutParams);
this.addView(infoLayout , infoLayoutParams);
}

private RelativeLayout createThumbnailLayout(Context context) {
RelativeLayout parentLayout = new RelativeLayout(context);
addThumbnailViewToThumbnailLayout(context, parentLayout);
addDurationViewToThumbnailLayout(context , parentLayout);
return parentLayout;
}

private LinearLayout createInfoLayout(Context context) {
LinearLayout parentLayout = new LinearLayout(context);
parentLayout.setOrientation(VERTICAL);
addTitleViewToInfoLayout(context , parentLayout);
addRewardViewToInfoLayout(context, parentLayout);
return parentLayout;
}

private void addThumbnailViewToThumbnailLayout(Context context, RelativeLayout parentLayout) {
thumbnailView = new ImageView(context);
RelativeLayout.LayoutParams thumbnaliParams = new RelativeLayout.LayoutParams(
dp2px(Constant.THUMBNAIL_WIDTH_DP), dp2px(Constant.THUMBNAIL_HEIGHT_DP)
);
thumbnaliParams.addRule(RelativeLayout.CENTER_IN_PARENT);
thumbnailView.setBackgroundColor(Color.BLACK);
parentLayout.addView(thumbnailView, thumbnaliParams);
}

private void addDurationViewToThumbnailLayout(Context context, RelativeLayout parentLayout) {
durationView = new TextView(context);
RelativeLayout.LayoutParams durationParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT
);
durationParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
durationParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
durationParams.rightMargin = dp2px(Constant.DURATION_MARGIN_RIGHT_DP);
durationParams.bottomMargin = dp2px(Constant.DURATION_MARGIN_BOTTOM_DP);
durationView.setPadding(
dp2px(Constant.DURATION_PADDING_DP),
dp2px(Constant.DURATION_PADDING_DP),
dp2px(Constant.DURATION_PADDING_DP),
dp2px(Constant.DURATION_PADDING_DP)
);
durationView.setBackgroundColor(Constant.DURATION_BACKGROUND_COLOR);
durationView.setTextColor(Constant.DURATION_TEXT_COLOR);
durationView.setTextSize(Constant.DURATION_TEXT_SIZE_SP);
parentLayout.addView(durationView, durationParams);
}

private void addTitleViewToInfoLayout(Context context, LinearLayout parentLayout) {
titleView = new TextView(context);
LinearLayout.LayoutParams titleViewParams = new LinearLayout.LayoutParams(
AbsListView.LayoutParams.MATCH_PARENT, 0
);
titleViewParams.weight = Constant.TITLE_WEIGHT;
titleView.setTextSize(Constant.TITLE_TEXT_SIZE);
titleView.setTextColor(Constant.TITLE_TEXT_COLOR);
titleView.setMaxLines(Constant.TITLE_MAX_LINE);
titleView.setEllipsize(Constant.TITLE_ELLIPSIZE);
titleView.setPadding(
dp2px(Constant.TITLE_PADDING_LEFT_DP),
dp2px(Constant.TITLE_PADDING_TOP_DP),
dp2px(Constant.TITLE_PADDING_RIGHT_DP),
dp2px(Constant.TITLE_PADDING_BOTTOM_DP)
);
parentLayout.addView(titleView, titleViewParams);
}

private void addRewardViewToInfoLayout(Context context, LinearLayout parentLayout) {
rewardView = new TextView(context);
LinearLayout.LayoutParams rewardViewParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT
);
rewardView.setTextSize(Constant.REWARD_TEXT_SIZE);
rewardView.setTextColor(Constant.REWARD_TEXT_COLOR);
rewardView.setGravity(Constant.REWARD_GRAVITY);
rewardView.setPadding(
dp2px(Constant.REWARD_PADDING_LEFT_DP),
dp2px(Constant.REWARD_PADDING_TOP_DP),
dp2px(Constant.REWARD_PADDING_RIGHT_DP),
dp2px(Constant.REWARD_PADDING_BOTTOM_DP)
);
parentLayout.addView(rewardView, rewardViewParams);
}
}

なんとか書き換えることができました。。。Android Studioではlayout.xmlを作成するときにGUIでプレビューしながら作成できるのですが、javaで作成する場合はプレビューできないので辛かったです。
これで冒頭の画像のように事前にダウンロードした動画の一覧を表示できるようになりました。

  1. 動画のダウンロード <- OK!!
  2. 動画の一覧表示 <- OK!!
  3. 動画の再生 <- Coming soon!

残すは動画の再生のみになりました。本ライブラリのメインになりますのでお楽しみに!