레이아웃 인플레이션
메모리에 올라가서 객체가 되는 과정이다 그렇게 인플레이션 된 레이아웃을 setContentView 메소드로
레이아웃 파일과 매칭 시키는 것이다.
(보통 메인클래스에 setContentView(R.id.activity_main) 이렇게 되어있다 )
하지만 보여지는 화면에 하나의 레이아웃 파일만 있으라는 법은 없다 그래서
한개의 화면에 다른 레이아웃화면을 띄울 때 나머지 레이아웃도 인플레이션 해주어야 하는데
그것을 아래의 코드로 할 수 있다.
getSystemService(Context.LAYOUT_INFLATER_SERVICE) 를 사용하여 해줄수 있다.
(다른 레이아웃.xml 파일을 인플레이션 해주는 기능)
package com.example.chap11;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
public class MainActivity extends AppCompatActivity {
CheckBox checkBox;
LinearLayout layout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
layout = findViewById(R.id.layout);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { // 다른 xml 불러와서 나의 화면에 띄워 주는것인데
//1번 방법 인플레이션 (컨택스트 정보가 있을땐 getLayoutInflater() 이렇게 사용)
// (컨택스트 정보가 없을땐 getLayoutInflater().from(context) 이렇게 사용 )
LayoutInflater inflater = getLayoutInflater();
//2번 방법 인플레이션 원래사용하던 예전 방법
// LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
// 인플레이션 속의 inflate 메소드로 인플레이션 해준다
// 1)해당 레이아웃 2)넣을 곳 3)그냥 true ( 붙이겠다는거에 동의같은 의미 )
inflater.inflate(R.layout.sub , layout ,true);
checkBox = layout.findViewById(R.id.checkBox);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
checkBox.setText("선택되었습니다.");
}else{
checkBox.setText("");
}
}
});
}
});
}
}
아래 주석을 잘 보면 된다
나의 엑티비티에 다른 엑티비티를 붙있때 인플레이션 하고 붙이는걸 볼수 있다.
온클릭 위쪽 주석이 중요하다 , 원래 사용하던 방식과 새롭게 생겨난 방법이 있는데 두개다 사용가능하지만 기왕이면 짧고 간결한게 좋겠지?
그리고 context 정보를 아는 곳에서 사용할땐 크게 문제가 되지 않지만 새로운 클래스에서 할때는 .from(contxt) 를 해줘야 한다
그럼 이번엔 자바소스로 하는 방법도 하나 살펴 보도록하자
자바소스 ( 뷰클래스)
public class Person extends LinearLayout {
Context context;
TextView textView;
ImageView imageView;
Button button;
public Person(Context context) {
//★2 메인에서 객체를 생성하면서 보낸 context를 여기에 설정 생성자실행되면서 init 메소드 실행
super(context);
this.context = context;
init();
}
public void init(){
//★3 생성자에서 이 메소드를 실행 하게 되고 이 클래스자체를 뷰클래스로 변환 하기위한 인플레이터
//뷰클래스로 변환 시키는 인플레이터
//LayoutInflater inflater = (LayoutInflater)context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
//★3-1 인플레이터 해줌
LayoutInflater inflater = LayoutInflater.from(context);
//pager레이아웃을 , 여기에 (this) , 인플레이터 해주겠다
inflater.inflate(R.layout.activity_pager, this, true);
//인플레이터 해주었기 때문에 이 클래스는 뷰 클래스로 변환이 되었고
// 변환이 되었기 때문에 여기에서 아이디를 참조하여 사용할수 있다.
textView = findViewById(R.id.textView);
imageView = findViewById(R.id.imageView);
button = findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String number = (String)button.getTag();
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("tel:"+number));
context.startActivity(intent);
}
});
}
//어댑터에서 이 메소드를 통하여 레이아웃에 그림과 글을 셋팅 해줌
public void setName(String name){
textView.setText(name);
}
public void setImage(int id){
imageView.setImageResource(id);
}
public void setCall_Btn(String number){
button.setText(number);
button.setTag(number);
}
}
메인클래스
public class MainActivity extends AppCompatActivity {
// ★4이제 person뷰 클래스에 정보를 담아 뷰페이저에 넣어 줘야하는데
// 어댑터를 사용하여 정보를 담아줌
ViewPager viewPager;
String[] names = {"트와이스" , "여자친구", "레드벨벳", " 블랙핑크"};
int[] id = {R.drawable.jeju1, R.drawable.jeju2, R.drawable.jeju3 , R.drawable.jeju4};
String[] call_num = {"010-1000-1000","010-2000-2000","010-3000-3000","010-4000-4000"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = findViewById(R.id.pager);
// 아래에 우리가 만든 어탭터 ★6어탭서 생성
ViewPagerAdapter adapter = new ViewPagerAdapter(this);
//뷰페이저에 만든 어탭터 껴줌
viewPager.setAdapter(adapter); // ★7생성된 어댑터를 뷰페이저에 셋팅준다
//이길이 만큼만 화면을 만들겠다는 것 (실수로 내용이 없는 화면이 만들어지는것 방지)
viewPager.setOffscreenPageLimit(names.length);
}
//어댑터 만든거 중간자 역활을 한다 ★5 어댑터 만들고
class ViewPagerAdapter extends PagerAdapter {
Context context;
public ViewPagerAdapter(Context context) {
this.context = context;
}
//아래 두개 임플리먼트로로 가져옴
@Override
public int getCount() {
//1. 현재 PagerAdapter 관리할 페이지의 수
return names.length;
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
//3. instantiateItem메소드에서 생성한 객체가 뷰페이저와 확인 하는 메소드
return view.equals(object);
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
//2. viewPager에서 사용할 뷰 객체를 생성 및 등록
Person person = new Person(context); //★1. 여기서 객체 생성할때 context 정보를 보내주면 Person 에서 받는다
person.setName(names[position]); // 눈에 보이진 않지만 만든만큼 for문처럼 돈다
person.setImage(id[position]);
person.setCall_Btn(call_num[position]);
container.addView(person,position);
return person;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
//4. 화면에 보이지 않는 View 객체를 삭제해서 관리 (메모리에 보이는 내용만 가지고 있고 나머지는 지움)
container.removeView((View)object);
}
}
}
일단 순서를 보면 메인에 뷰페이저에 다른 xml을 띄울려고 한다
그런데 뷰페이저를 사용할려면 어댑터를 써야해서 어댑터를 먼저 만들어주었다
(단순 순서)
그리고 xml을 만들어주고 이 xml을 관리할 person클래스를 만들어주었다. person은 그냥 클래스 이므로 리니어 레이아웃을 상속받고 인플레이션을 통해 이 클래스는 뷰클래스로서 바뀌게 된다 자 뷰클래스로 받아서 이제 메인에 들어갈수는 있는상황이지만 아무런 데이터가 없는상황 데이터는 메인에 있다
자 이제 메인에서 가진 데이터를 어댑터를 통해 넣어주고(어댑터는 나중에 배운다 ) 그 어댑터를 통해 뷰클래스의 정보들을 변경할수 있는 것이다 .
보이는것처럼 전체 레이아웃이 있고 그 안에 새로운 레이아웃을 추가한것을 볼수 있다
'아옳옳의 코딩공부 > 아옳옳의 안드로이드스튜디오' 카테고리의 다른 글
2021-03-23안드로이드 스튜디오(브로드캐스트) (0) | 2021.03.23 |
---|---|
2021-03-22안드로이드 스튜디오(서비스 ) (0) | 2021.03.22 |
2021-03-18 안드로이드 스튜디오( 사용자 이벤트 처리와 리소스2 ,애니메이션) (0) | 2021.03.18 |
2021-03-17 안드로이드 스튜디오( 태스크3 , 사용자 이벤트 처리와 리소스 활용 ) (0) | 2021.03.17 |
2021-03-16 안드로이드 스튜디오( 태스크2) (0) | 2021.03.16 |