프래그먼트를 사용하여 공유 요소 전환을 시작하는 방법은 무엇입니까?
새로운 머티리얼 디자인 사양에 설명 된대로 "공유 요소"가있는 프래그먼트 전환을 구현합니다. 내가 유효한 유일한 방법은 ActivityOptionsCompat.makeSceneTransitionAnimation 이며 Activity에서 작동한다고 생각합니다. 나는이 동일한 기능을 찾고 있었지만 조각이 있습니다.
나는 같은 문제가 있었지만 다른 조각에서 새 조각을 추가하여 작동했습니다. 다음 링크는 시작하는 데 매우 유용합니다. https://developer.android.com/training/material/animations.html#Transitions
다음은 작동하는 내 코드입니다. ImageView
한 조각에서 다른 조각으로 애니메이션을 적용하고 있습니다. View
애니메이션하려는이 android:transitionName
두 조각에서 모두 동일 해야합니다 . 다른 내용은별로 중요하지 않습니다.
테스트로 관리자 두 레이아웃 xml 파일에 복사 할 수 있습니다. 이미지가 있는지 확인하십시오.
<ImageView
android:transitionName="MyTransition"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/test_image" />
그런 다음 내 res/transition
폴더에 change_image_transform.xml 이라는 파일이 하나 있습니다.
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<changeImageTransform />
</transitionSet>
이제 시작할 수 있습니다. 이미지가 포함 된 조각 A가 있고있는 조각 B를 추가하려고 가정 해 보겠습니다.
조각 A에서 실행하십시오.
@Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.product_detail_image_click_area:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setSharedElementReturnTransition(TransitionInflater.from(getActivity()).inflateTransition(R.transition.change_image_transform));
setExitTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.explode));
// Create new fragment to add (Fragment B)
Fragment fragment = new ImageFragment();
fragment.setSharedElementEnterTransition(TransitionInflater.from(getActivity()).inflateTransition(R.transition.change_image_transform));
fragment.setEnterTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.explode));
// Our shared element (in Fragment A)
mProductImage = (ImageView) mLayout.findViewById(R.id.product_detail_image);
// Add Fragment B
FragmentTransaction ft = getFragmentManager().beginTransaction()
.replace(R.id.container, fragment)
.addToBackStack("transaction")
.addSharedElement(mProductImage, "MyTransition");
ft.commit();
}
else {
// Code to run on older devices
}
break;
}
}
나는 여기에 새로 왔고 댓글을 달 수 없기 때문에 대답으로 게시하고 있습니다.
공유 요소 조각 전환 은 소스 및 대상 뷰가 동일한 (및 고유 한) transitionName을 장치 한 ListView에서 작동합니다.
당신이 당신의 목록보기 어댑터가 원하는 뷰 (예 : 일부 일정 + 특정 항목 ID)에 고유 한 transitionNames을 설정 한 경우 도 계명 런타임에 목표 조회수 (onCreateView)에 동일한 transitionNames을 설정하여 세부 조각을 변경 전환 실제로 작업 !
공유 요소는 프래그먼트와 함께 작동하지만 몇 가지 유의해야 할 사항이 있습니다.
설정하려고하지을 마십시오
sharedElementsTransition
에onCreateView
당신의 조각. 조각의 인스턴스를 만들 때 또는onCreate
.진입 / 종료 전환 sharedElementTransition의 가능한 애니메이션에 대한 공식 문서를 기록해 두십시오. 그들은 동일하지 않습니다.
시행 착오 :)
내가 주문하신다고 할 수 없기 때문에 받아 들여진 대답에 대한 주석이어야합니다.
허용 된 답변 (WindsurferOak 및 ar34z)은 backStack으로 탐색 할 때 널 포인터 예외를 발생시킨 "사소한"문제를 제외하고 작동합니다. setSharedElementReturnTransition()
원래 조각 대신 대상 조각에서 호출해야 할 것 입니다.
그래서 대신 :
setSharedElementReturnTransition(TransitionInflater.from(getActivity()).inflateTransition(R.transition.change_image_transform));
그것은해야한다
fragment.setSharedElementReturnTransition(TransitionInflater.from(getActivity()).inflateTransition(R.transition.change_image_transform));
https://github.com/tevjef/Rutgers-Course-Tracker/issues/8
다음은 몇 가지 유용한 리소스입니다.
https://github.com/lgvalle/Material-Animations
https://www.youtube.com/watch?v=5e1Yh0fSZhQ
핵심은 사용자 지정 트랜잭션을 사용하는 것입니다.
transaction.addSharedElement(sharedElement, "sharedImage");
두 조각 연주 공유 요소 전환
이 예에서, 가지 중 하나 두 ImageViews
로부터 번역되어야 ChooserFragment
받는 DetailFragment
.
에서 ChooserFragment
레이아웃 우리 고유의 필요 transitionName
특성을 :
<ImageView
android:id="@+id/image_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_first"
android:transitionName="fistImage" />
<ImageView
android:id="@+id/image_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_second"
android:transitionName="secondImage" />
에서 ChooserFragments
클래스, 우리는 필요가 View
클릭과 부모에 대한 ID 된 Activity
조각의 교체를 처리 느릅 나무 (우리는 표시 할 이미지 리소스를 알고 ID를 필요로합니다 DetailFragment
). 정보를 부모 활동에 전달하는 방법은 다른 문서에서 확실히 다룹니다.
view.findViewById(R.id.image_first).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mCallback != null) {
mCallback.showDetailFragment(view, 1);
}
}
});
view.findViewById(R.id.image_second).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mCallback != null) {
mCallback.showDetailFragment(view, 2);
}
}
});
에서 DetailFragment
의 ImageView
공유 요소는 고유 한 요구 transitionName
속성을.
<ImageView
android:id="@+id/image_shared"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:transitionName="sharedImage" />
의 메소드 onCreateView()
에서 DetailFragment
표시 할 이미지 리소스를 결정해야합니다 (그렇게하지 공유 요소가 전환 후 사라집니다).
public static DetailFragment newInstance(Bundle args) {
DetailFragment fragment = new DetailFragment();
fragment.setArguments(args);
return fragment;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.fragment_detail, container, false);
ImageView sharedImage = (ImageView) view.findViewById(R.id.image_shared);
// Check which resource should be shown.
int type = getArguments().getInt("type");
// Show image based on the type.
switch (type) {
case 1:
sharedImage.setBackgroundResource(R.drawable.ic_first);
break;
case 2:
sharedImage.setBackgroundResource(R.drawable.ic_second);
break;
}
return view;
}
부모 Activity
는 반환을 수신하고 조각의 교체를 처리합니다.
@Override
public void showDetailFragment(View sharedElement, int type) {
// Get the chooser fragment, which is shown in the moment.
Fragment chooserFragment = getFragmentManager().findFragmentById(R.id.fragment_container);
// Set up the DetailFragment and put the type as argument.
Bundle args = new Bundle();
args.putInt("type", type);
Fragment fragment = DetailFragment.newInstance(args);
// Set up the transaction.
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Define the shared element transition.
fragment.setSharedElementEnterTransition(new DetailsTransition());
fragment.setSharedElementReturnTransition(new DetailsTransition());
// The rest of the views are just fading in/out.
fragment.setEnterTransition(new Fade());
chooserFragment.setExitTransition(new Fade());
// Now use the image's view and the target transitionName to define the shared element.
transaction.addSharedElement(sharedElement, "sharedImage");
// Replace the fragment.
transaction.replace(R.id.fragment_container, fragment, fragment.getClass().getSimpleName());
// Enable back navigation with shared element transitions.
transaction.addToBackStack(fragment.getClass().getSimpleName());
// Finally press play.
transaction.commit();
}
잊지 마세요 Transition
. 이 예제는 공유 요소를 이동하고 크기를 조정합니다.
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class DetailsTransition extends TransitionSet {
public DetailsTransition() {
setOrdering(ORDERING_TOGETHER);
addTransition(new ChangeBounds()).
addTransition(new ChangeTransform()).
addTransition(new ChangeImageTransform());
}
}
조각에서 SharedElement를 검색하고 GitHub에서 매우 유용한 소스 코드를 찾았습니다.
1. 먼저 두 조각 레이아웃에서 개체 (ImageView와 유사)에 대한 transitionName 을 정의해야 합니다 (클릭 이벤트를 처리하기 위해 조각 A에 버튼을 추가합니다).
단편 A :
<ImageView
android:id="@+id/fragment_a_imageView"
android:layout_width="128dp"
android:layout_height="96dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="80dp"
android:scaleType="centerCrop"
android:src="@drawable/gorilla"
android:transitionName="@string/simple_fragment_transition />
<Button
android:id="@+id/fragment_a_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="24dp"
android:text="@string/gorilla" />
단편 B :
<ImageView
android:id="@+id/fragment_b_image"
android:layout_width="match_parent"
android:layout_height="250dp"
android:scaleType="centerCrop"
android:src="@drawable/gorilla"
android:transitionName="@string/simple_fragment_transition" />
- 그런 다음 전환 디렉토리의 전환 파일 에이 코드를 작성해야합니다 (이 디렉토리가 하나를 작성해야합니다 : res> new> Android Resource Directory> Resource Type = transition> name = change_image_transform).
change_image_transform.xml :
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<changeBounds/>
<changeTransform/>
<changeClipBounds/>
<changeImageTransform/>
</transitionSet>
- 마지막 단계에서 자바로 코드를 완성해야합니다.
단편 A :
public class FragmentA extends Fragment {
public static final String TAG = FragmentA.class.getSimpleName();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_a, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final ImageView imageView = (ImageView) view.findViewById(R.id.fragment_a_imageView);
Button button = (Button) view.findViewById(R.id.fragment_a_btn);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getFragmentManager()
.beginTransaction()
.addSharedElement(imageView, ViewCompat.getTransitionName(imageView))
.addToBackStack(TAG)
.replace(R.id.content, new FragmentB())
.commit();
}
});
}
}
단편 B :
public class FragmentB extends Fragment {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setSharedElementEnterTransition(TransitionInflater.from(getContext()).inflateTransition(android.R.transition.move));
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_b, container, false);
}
}
활동에서 "A"조각을 표시하는 것을 잊지 않습니다.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportFragmentManager()
.beginTransaction()
.add(R.id.content, new SimpleFragmentA())
.commit();
}
출처 : https://github.com/mikescamell/shared-element-transitions
참조 URL : https://stackoverflow.com/questions/26561579/how-to-start-shared-element-transition-using-fragments
'ProgramingTip' 카테고리의 다른 글
Node.js Port 3000이 이미 사용 중이지만 실제로는 말입니까? (0) | 2020.12.26 |
---|---|
JSON 스키마에 선언 된 속성 만 허용 (0) | 2020.12.25 |
Android-CoordinatorLayout에서 사용하면 바닥 글이 화면 외 스크롤됩니다. (0) | 2020.12.25 |
Android에서 ClipData의 "label"매개 변수는 정확히 무엇입니까? (0) | 2020.12.25 |
실행되지 않은 코드가 주석 처리되면 Java 프로그램이 느리게 실행됩니다. (0) | 2020.12.25 |