23
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Custom Viewsで複数のviewを1つにまとめて部品化する

Last updated at Posted at 2017-09-07
1 / 11

##問題

  • アプリ内に同じような表示箇所が複数あり、それぞれを修正するのが辛い:fearful:
  • 下記のような、複数の場所で表示するパーツ
スクリーンショット 2017-09-06 17.32.31.png

##解決案

  • 複数のviewを1つのクラスにまとめて、表示ロジックもそのクラス内で完結させたい。
  • Custom Viewを使う。
  • 今回はRelativeLayoutを継承したクラスを作る。

##Custom Viewとは
Creating Custom Views

  • 既存のviewをカスタマイズして使いやすいようにする。
  • 例えば、正方形の画像が欲しい時はImageViewをextendsしたクラスを作成してonMeasure()をオーバライドする。
  • レイアウトXMLをコピペして作ってる箇所は置き換えられるかもしれません。

##修正ファイル

  • レイアウトXML
  • viewをextendsしたクラス
  • Activityのクラス
  • ActiivtyのレイアウトXML
  • attrs.xml (レイアウトXMLから値を取得したい場合。これは今回は説明しません。)

##レイアウトXML

  • XMLを作成します。
custom_image_view.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- mergeで不必要なviewGrouの階層を作らないようにする -->
<merge
    xmlns:android="http://schemas.android.com/apk/res/android">

    <ImageView
        android:id="@+id/icon"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="12dp"
        />

    <TextView
        android:id="@android:id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

    <TextView
        android:id="@+id/description"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

</merge>


##viewをextendsしたクラス

CustomImageView.java
public class CustomImageView extends RelativeLayout {
    private Context mContext;

    <!-- コンストラクタは3つ用意しました API21からは4つのコンストラクタが使えるようです-->
    public CustomImageView(Context context) {
        this(context, null);
    }

    public CustomImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        mContext = context;

        LayoutInflater inflater = LayoutInflater.from(context);
        inflater.inflate(R.layout.custom_image_view, this, true);
    }

    public void setInfo(String title, String description, String imageUrl) {
        ImageView imageView = findViewById(R.id.icon);
        
        Glide.with(getApplicationContext())
                .load(imageUrl)
                .placeholder(R.drawable.placeholder)
                .into(imageView);

        ((TextView) findViewById(R.id.title)).setText(title);
        ((TextView) findViewById(R.id.description)).setText(description);
        invalidate();
    }
}


##customViewを利用するActivityのクラス

MainActivity.java

public class MainActivity extends AppCompatActivity {

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

        CustomImageView custom = (CustomImageView) this.findViewById(R.id.custom);
        custom.setInfo("title", "description", "画像URL");
    }
}


##ActivityのレイアウトXML

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

    <sample.com.test_customview.CustomImageView
        android:id="@+id/custom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

</LinearLayout>


##終わりに

  • 見た目や処理を1つにまとめられるので便利です。

参考資料

23
22
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?