LinearLayout 상속하여 직접 만들기
layout을 상속해서 직접 만들려면 보여질 layout파일과 연결하여 사용할 java 파일이 필요하다. 여기서 layout 파일은 실제로 화면에 보여질 때 전체 화면이 아니고 부분화면이 된다.
lyaout1.xml 이름으로 새로운 layout을 만들었다.
<?xml version="1.0" encoding="utf-8"?>
<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=".Layout1">
<ImageView
android:id="@+id/imageView"
android:layout_width="80dp"
android:layout_height="80dp"
android:padding="5dp"
app:srcCompat="@mipmap/ic_launcher" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="이름"
android:textSize="30sp" />
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="전화번호"
android:textColor="#FF0000FF"
android:textSize="25sp" />
</LinearLayout>
</LinearLayout>
layout1.xml
Layout1.java 파일을 xml의 최상위 레이아웃인 LinearLayout 을 상속받아서 만들었다.
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class Layout1 extends LinearLayout {
public Layout1(Context context) {
super(context);
init(context);
}
public Layout1(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.layout1, this, true);
}
public void setImage(int resId) {
imageView.setImageResource(resId);
}
public void setName(String name) {
textView.setText(name);
}
public void setMobile(String mobile) {
textView2.setText(mobile);
}
}
Layout1.java
생성자를 만들어야한다.
객체가 생성될 때 호출될 수 있도록 init() 메서드를 추가한다. init() 메서드는 Context 객체가 전달되며 그 안에서 XML 레이아웃 파일을 인플레이션하여 이 소스 파일과 매칭될 수 있도록 한다.
초기화작업에서 중요한 것이 , 두개의 파일을 연결하는 것이다. 이것이 바로 layout inflation이다.
LayoutInflater 객체를 쓸 수 있도록 만들고, xml과 연결한다.
(LayoutInflater 객체는 시스템 서비스로 제공되므로 getSystemService() 메서드를 호출하면서 파라미터로 Context.LAYOUT_INFLATER_SERVICE 상수를 전달하면 객체가 반환된다. 이 객체의 inflate() 메서드를 호출하면서 XML 레이아웃 파일을 파라미터로 전달하면 인플레이션이 진행되면서 이 소스 파일에 설정된다.)
인플레이션이 끝나면 layout1.xml 파일에 넣어둔 이미지뷰나 텍스트뷰를 찾아서 참조할 수 있다.
public class Layout1 extends LinearLayout {
TextView textView1;
TextView textView2;
ImageView imageView;
...
private void init(Context context) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.layout1, this, true);
imageView = findViewById(R.id.imageView);
textView = findViewById(R.id.textView);
textView2 = findViewById(R.id.textView2);
}
//클래스 밖에서도 사용할 수 있도록 메소드 추가하기.
public void setImage(int resId){
imageView.setImageResource(resId);
}
public void setName(String name){
textView1.setText(name);
}
public void setMobile(String mobile){
textView2.setText(mobile);
}
}
Layout1.java
setImage()는 정수를 전달받아 이미지뷰의 이미지를 변경할 수 있도록 한다.
setImageResource()는 이미지뷰에 보이는 이미지를 바꿀 수 있는 메서드 중 하나이다. app/res/drawable 폴더 안에 들어있는 이미지 파일을 참조하는 정수값을 파라미터로 전달받는다. (이미지 파일은 내부적으로 정수값으로 표현된다.)
레이아웃을 상속한 새로운 레이아웃이 만들어졌다. 이제 화면에 추가해보자.
<?xml version="1.0" encoding="utf-8"?>
<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"
android:orientation="vertical"
tools:context=".MainActivity" >
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="이미지바꾸기"
app:backgroundTint="#818EDA" />
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="#FFFFFF"
app:cardCornerRadius="10dp"
app:cardElevation="5dp"
app:cardUseCompatPadding="true">
<org.techtown.mylayout3.Layout1
android:id="@+id/layout1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</androidx.cardview.widget.CardView>
</LinearLayout>
mainActivity.java
mainActivity 에 내가 만든 layout을 추가해보자.
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
Layout1 layout1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
layout1 = findViewById(R.id.layout1);
layout1.setImage(R.drawable.ic_android_black_24dp);
layout1.setName("aji");
layout1.setMobile("010-1000-1000");
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
layout1.setImage(R.drawable.ic_baseline_adb_24);
}
});
}
}
MainActivity.java
layout1.xml 화면은 activity.xml 에서 부분적인 화면으로 보여진다.
layout1.xml 에 있는 이미지와 글자를 바꾸고 싶다면, Layout1.java 에 있는 객체를 통해 바꿀 수 있다.