programing

프래그먼트로 데이터 바인딩을 사용하는 방법

telebox 2023. 8. 10. 18:43
반응형

프래그먼트로 데이터 바인딩을 사용하는 방법

저는 공식 구글 문서 https://developer.android.com/tools/data-binding/guide.html 의 데이터 바인딩 예를 따르려고 합니다.

데이터 결합을 활동이 아닌 단편에 적용하려는 것을 제외하고는 말입니다.

현재 컴파일할 때 발생하는 오류는

Error:(37, 27) No resource type specified (at 'text' with value '@{marsdata.martianSols}.

onCreatefragment의 경우 다음과 같습니다.

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    MartianDataBinding binding = MartianDataBinding.inflate(getActivity().getLayoutInflater());
    binding.setMarsdata(this);
}

onCreateViewfragment의 경우 다음과 같습니다.

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    return inflater.inflate(R.layout.martian_data, container, false);
}

그리고 fragment에 대한 레이아웃 파일의 일부는 다음과 같습니다.

<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="marsdata"
            type="uk.co.darkruby.app.myapp.MarsDataProvider" />
    </data>
...

        <TextView
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:text="@{marsdata.martianSols}"
        />

    </RelativeLayout>
</layout>

나의 의심은 …입니다.MartianDataBinding어떤 레이아웃 파일로 바인딩되어야 하는지 알 수 없으므로 오류가 발생합니다.좋은 의견이라도 있나?

데이터 바인딩 구현은 다음에 있어야 합니다.onCreateViewfragment의 방법, 당신의 안에 존재하는 모든 데이터 바인딩을 삭제하세요.OnCreate메서드, 사용자의onCreateView다음과 같이 표시됩니다.

public View onCreateView(LayoutInflater inflater, 
                         @Nullable ViewGroup container, 
                         @Nullable Bundle savedInstanceState) {
    MartianDataBinding binding = DataBindingUtil.inflate(
            inflater, R.layout.martian_data, container, false);
    View view = binding.getRoot();
    //here data must be an instance of the class MarsDataProvider
    binding.setMarsdata(data);
    return view;
}

실제로 사용할 것을 권장합니다.inflateDataBindingUtil이 아닌 생성된 바인딩의 메서드:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    MainFragmentBinding binding = MainFragmentBinding.inflate(inflater, container, false);
    //set variables in Binding
    return binding.getRoot();
}

(R.layout.main_fragment에 대해 MainFragmentBinding이 자동으로 생성됨)

DataBindingUtil.plate()대한 문서:

layoutId를 미리 알 수 없는 경우에만 이 버전을 사용합니다.그렇지 않으면 생성된 바인딩의 팽창 방법을 사용하여 유형 안전 팽창을 보장합니다.

ViewModel 및 LiveData사용하는 경우 이 구문으로 충분합니다.

코틀린 구문:

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    return MartianDataBinding.inflate(
        inflater,
        container,
        false
    ).apply {
        lifecycleOwner = viewLifecycleOwner
        vm = viewModel    // Attach your view model here
    }.root
}

대부분이 말했듯이 라이프사이클 오너를 설정하는 것을 잊지 마십시오.
Java의 샘플(예:

public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
    super.onCreateView(inflater, container, savedInstanceState);
    BindingClass binding = DataBindingUtil.inflate(inflater, R.layout.fragment_layout, container, false);
    ModelClass model = ViewModelProviders.of(getActivity()).get(ViewModelClass.class);
    binding.setLifecycleOwner(getActivity());
    binding.setViewmodelclass(model);

    //Your codes here

    return binding.getRoot();
}

Android Data Binding에서 사용해 보십시오.

FragmentMainBinding binding;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_main, container, false);
        View rootView = binding.getRoot();
        initInstances(savedInstanceState);
        return rootView;
}

코틀린 구문:

lateinit var binding: MartianDataBinding
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    binding = DataBindingUtil.inflate(inflater, R.layout.martian_data, container, false)
    return binding.root
}

아래에 설명된 대로 보기 개체를 검색할 수 있습니다.

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

View view = DataBindingUtil.inflate(inflater, R.layout.layout_file, container, false).getRoot();

return view;

}

데이터 바인딩 프래그먼트의 완전한 예

FragmentMyProgramsBinding은 res/layout/fragment_my_programs에 대해 생성된 바인딩 클래스입니다.

public class MyPrograms extends Fragment {
    FragmentMyProgramsBinding fragmentMyProgramsBinding;

    public MyPrograms() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
    FragmentMyProgramsBinding    fragmentMyProgramsBinding = DataBindingUtil.inflate(inflater, R
                .layout.fragment_my_programs, container, false);
        return fragmentMyProgramsBinding.getRoot();
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

    }
}

내 코드로 일하는 것.

private FragmentSampleBinding dataBiding;
private SampleListAdapter mAdapter;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    super.onCreateView(inflater, container, savedInstanceState);
    dataBiding = DataBindingUtil.inflate(inflater, R.layout.fragment_sample, null, false);
    return mView = dataBiding.getRoot();
}

코틀린에서 할 수 있는 방법은 다음과 같습니다.

//Pass the layout as parameter to the fragment constructor    
class SecondFragment : Fragment(R.layout.fragment_second) {

    private var _binding: FragmentSecondBinding? = null
    private val binding  get() = _binding!!

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        _binding = FragmentSecondBinding.bind(view)  //if the view is already inflated then we can just bind it to view binding.

    }

    //Note: Fragments outlive their views. Make sure you clean up any references to the binding class
    // instance in the fragment's onDestroyView() method.
    override fun onDestroyView() {
        Toast.makeText(activity, "On destroy", Toast.LENGTH_SHORT).show()
        super.onDestroyView()
        _binding = null
    }
}

레이아웃에서 다음과 같은 보기 요소에 액세스할 수 있습니다.

binding.tvName.text = "Messi"

여기서 tvName은 뷰 요소의 ID입니다.

나는 내 지원서에 대한 답을 찾고 있었고 여기 코틀린 언어에 대한 답이 있습니다.


private lateinit var binding: FragmentForgetPasswordBinding

override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?): View? {
    binding=DataBindingUtil.inflate(inflater,R.layout.fragment_forget_password,container,false)
    
    val viewModel=ViewModelProvider(this).get(ForgetPasswordViewModel::class.java)
    binding.recoveryViewModel=viewModel
    viewModel.forgetPasswordInterface=this
    return binding.root
}

코틀린의 또 다른 예:

override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    val binding = DataBindingUtil
            .inflate< MartianDataBinding >(
                    inflater,
                    R.layout.bla,
                    container,
                    false
            )

    binding.modelName = // ..

    return binding.root
}

"MartianDataBinding"이라는 이름은 레이아웃 파일의 이름에 따라 달라집니다.파일 이름이 "martian_data"이면 올바른 이름은 MartianDataBinding입니다.

데이터 바인딩에 대한 매우 유용한 블로그: https://link.medium.com/HQY2VizKO1

class FragmentBinding<out T : ViewDataBinding>(
    @LayoutRes private val resId: Int
) : ReadOnlyProperty<Fragment, T> {

    private var binding: T? = null

    override operator fun getValue(
        thisRef: Fragment,
        property: KProperty<*>
    ): T = binding ?: createBinding(thisRef).also { binding = it }

    private fun createBinding(
        activity: Fragment
    ): T = DataBindingUtil.inflate(LayoutInflater.from(activity.context),resId,null,true)
}

fragment에서 바인딩 값을 다음과 같이 선언합니다.

private val binding by FragmentBinding<FragmentLoginBinding>(R.layout.fragment_login)

이것을 단편적으로 쓰는 것을 잊지 마세요.

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    return binding.root
}

코틀린

         override fun onCreateView(
                 inflater: LayoutInflater, container: ViewGroup?,
                 savedInstanceState: Bundle?
            ): View? 
    { 
                 val binding = FragmentFirstBinding.inflate(inflater,container,false)      
               return  binding.root;
            

}

여기서 FragmentFirstBinding은 보기 바인딩을 사용하여 Android 스튜디오에서 자동으로 생성됩니다.내 코드 조각 이름은 FirstFragment입니다.

먼저 이 선을 빌드에 추가해야 합니다.Gradle(앱 모듈) 파일입니다.

buildFeatures{
        viewBinding true
    }

에 대해 모두가 말합니다.inflate()하지만 우리가 그것을 사용하고 싶다면요?onViewCreated()?

콘크리트 바인딩 클래스의 방법을 사용하여 다음을 얻을 수 있습니다.ViewDataBinding입니다.view.


일반적으로 BaseFragment는 다음과 같이 작성합니다(간체).

// BaseFragment.kt
abstract fun layoutId(): Int

override fun onCreateView(inflater, container, savedInstanceState) = 
    inflater.inflate(layoutId(), container, false)

그리고 그것을 어린이 조각에 사용합니다.

// ConcreteFragment.kt
override fun layoutId() = R.layout.fragment_concrete

override fun onViewCreated(view, savedInstanceState) {
    val binding = FragmentConcreteBinding.bind(view)
    // or
    val binding = DataBindingUtil.bind<FragmentConcreteBinding>(view)
}


모든 Fragments가 데이터 바인딩을 사용하는 경우 type 매개 변수를 사용하여 더 쉽게 만들 수도 있습니다.

abstract class BaseFragment<B: ViewDataBinding> : Fragment() {
    abstract fun onViewCreated(binding: B, savedInstanceState: Bundle?)

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        onViewCreated(DataBindingUtil.bind<B>(view)!!, savedInstanceState)
    }
}

거기서 null이 아니라고 주장하는 것이 괜찮은지는 모르겠지만..당신은 이해합니다.무효화하려면 가능합니다.

코틀린에서 가장 짧은 길;

class HomeFragment : Fragment(R.layout.fragment_home) {


override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    val binding = FragmentHomeBinding.bind(view)
    // todo 
    }

언급URL : https://stackoverflow.com/questions/34706399/how-to-use-data-binding-with-fragment

반응형