[Android, 안드로이드] ViewPager 사용시 Fragment 동적 처리방법
ViewPager 사용시 Fragment 동적 처리
ViewPager와 Fragment를 사용하여 앱 개발시 리시버로 부터 전달받은 데이터를 토대로 Fragment에 데이터를 전달하여 UI를 변경해야할 경우 참고하세요.
첫번째로 어댑터 클래스를 생성 후 리시버로 부터 리턴받을 메소드를 하나 구현합니다. 아래 코드에서 update() 메소드가 호출 되면 어댑터에게 데이터가 변경되었음을 알리는 notifyDataSetChanged()메소드를 호출하고 있습니다. 호출이 완료되면 getItemPosition()메소드가 자동으로 호출됩니다. 이 메소드 안에서 해당 Fragment인지 체크 후 updateUI()메소드를 호출합니다. updateUI()는 UpdateableFragment인터페이스 클래스를 하나 생성 후 빈 메소드를 선언합니다.
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.fragment.app.FragmentStatePagerAdapter;
import java.util.ArrayList;
import java.util.List;
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
String technology;
int status;
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
@Override
public int getItemPosition(@NonNull Object object) {
if (object instanceof HomeFragment) {
((UpdateableFragment) object).updateUI(status, technology);
}
//don't return POSITION_NONE, avoid fragment recreation.
return super.getItemPosition(object);
}
//call this method to update fragments in ViewPager dynamically
public void update(int _status, String _technology) {
status =_status;
technology = _technology;
notifyDataSetChanged();
}
public void addFrag(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
}
update()메소드에서 notifyDataSetChanged()를 호출해야 getItemPositon()메소드가 자동 호출 됩니다. 하지만 딜레이가 있기 때문에 바로 UI에 적용되지않는다. 바로 적용하려면 getItem()메소드를 오버라이드처리하여 Fragment에 데이터를 전달하여 처리해야한다.
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return HomeFragment.newInstance(status ,technology);
}
return mFragmentList.get(position);
}
[UpdateableFragment] 인터페이스
public interface UpdateableFragment {
public void updateUI(int status, String technology);
}
생성한 인터페이스를 데이터 전달이 필요한 프레그먼트에서 implements 처리 후 updateUI메소드를 오버라이드 처리합니다.
[HomeFragment] 클래스
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class HomeFragment extends Fragment implements UpdateableFragment {
private static final String ARG_PARAM1 = "status";
private static final String ARG_PARAM2 = "technology";
TextView status_text;
String technology;
int status;
public static HomeFragment newInstance(int status, String technology) {
HomeFragment fragment = new HomeFragment();
Bundle args = new Bundle();
args.putInt(ARG_PARAM1, status);
args.putString(ARG_PARAM7, technology);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
status = getArguments().getInt(ARG_PARAM1);
technology = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
status_text = view.findViewById(R.id.ratio_text);
// Inflate the layout for this fragment
status_text.setText(technology);
return view;
}
@Override
public void updateUI(int _status, String _technology) {
status =_status;
technology = _technology;
//UI 처리
status_text.setText(technology);
}
}
[fragment_home.xml]
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
tools:context=".HomeFragment">
<TextView
android:id="@+id/status_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="홈" />
</FrameLayout>
[브로드케스터 리시버에서 처리]
private BroadcastReceiver mainViewReceiver = new BroadcastReceiver() {
Intent bIntent;
@Override
public void onReceive(Context context, Intent receiveIntent) {
this.bIntent = receiveIntent;
String action = bIntent.getAction();
if (bIntent != null && action != null) {
fragmentViewPagerAdapter.update(
,bIntent.getIntExtra("PARAM1")
,bIntent.getStringExtra("PARAM2"));
}
}
};
[MainActivity] 클래스
ViewPagerAdapter fragmentViewPagerAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager viewPager = findViewById(R.id.viewpager);
TabLayout tabLayout = findViewById(R.id.tablayout);
//어댑터 할당
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentViewPagerAdapter = new MyViewPagerAdapter(fragmentManager);
//프레그먼트 추가
fragmentViewPagerAdapter.addFrag(new HomeFragment(), "홈");
fragmentViewPagerAdapter.addFrag(new SettingsFragment(), "설정");
fragmentViewPagerAdapter.addFrag(new NotiFragment(), "알림");
// 뷰페이저에 어댑터 설정
viewPager.setAdapter(fragmentViewPagerAdapter);
//탭레이아웃에 뷰페이저 설정
tabLayout.setupWithViewPager(viewPager);
}
[연관]
[Android] TabLayout과 ViewPager 함께 사용하는 방법 (Fragment)
[Android] ViewPager.OnPageChangeListener() deprecated 에 따른 대체 메소드 addOnPageChangeListener() 사용하기
[참고]

