다중 창 레이아웃을 간단하게 실현하는 방법
18303 단어 Android
개시하다
다중 창 레이아웃에 대한 설명은 생략합니다.
http://developer.android.com/design/patterns/multi-pane-layouts.html
다중 창 레이아웃에서 왼쪽 창을 Master/Detail 모드라고 합니다.
이 마스터/Detail 모드의 다중 창 설치는 SlidingPaneLayout
를 사용합니다.
SlidingPaneLayout SlidingPaneLayout
는 r18부터 SupportLibrary에 포함된 비교적 새로운 ViewGroup입니다.
https://developer.android.com/reference/android/support/v4/widget/SlidingPaneLayout.html
기능은 대체로 다음과 같다.
SlidingPaneLayout
는 r18부터 SupportLibrary에 포함된 비교적 새로운 ViewGroup입니다.https://developer.android.com/reference/android/support/v4/widget/SlidingPaneLayout.html
기능은 대체로 다음과 같다.
SlidingPaneLayout
만 사용하면 최소한의 다중 창 대응이 가능합니다.하지만 자동화는 정말 최소한의 일일 뿐이다.
외관
세로 화면
→
수평 화면
첫 번째 그림에서 세부 패널이 회색으로 바뀌었습니다. 이것은 SlidingPaneLayout
자동 필터입니다.
이루어지다
우선, 배치는 다음과 같다.
목록 영역과 내용 영역에 각각 지정android:layout_width
하여 터미널의 너비가 합계 이상인 경우 나란히 표시하고 부족한 경우 슬라이드 디스플레이를 전환할 수 있습니다.
내용 영역에 지정android:layout_weight
을 통해 터미널의 폭이 580dp보다 크면 내용 영역을 공백 부분으로 확장할 수 있습니다.
또한 컨텐츠 영역에 android:background
가 지정되어 있지만 슬라이드에 숨겨진 그림자 묘사가 이상하게 변하는 경우가 있으므로 무언가를 지정하는 것이 좋습니다.
fragment_slidingpanel.xml<android.support.v4.widget.SlidingPaneLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@android:id/list"
android:layout_width="280dp"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@+id/content"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@android:color/white" />
</android.support.v4.widget.SlidingPaneLayout>
Fragment 설치는 목록 측면SlidingPaneLayout
측면에만 표시됩니다.
자세한 패널의 이동 처리만 쓰고 이동할 때 메뉴 옆의 처리를 닫습니다.
기타 다중 창과 슬라이드 애니메이션 등SlidingPaneLayout
은 자동으로 진행됩니다.SlidingPaneLayout
와 리스트 패널의 설치가 같다Fragment
는 간소화의 비결이다.
SlidingPanelFragment.javapublic class SlidingPanelFragment extends Fragment {
SlidingPaneLayout mSlidingPaneLayout;
public SlidingPanelFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_slidingpanel, container, false);
mSlidingPaneLayout = (SlidingPaneLayout) view.findViewById(R.id.sliding_pane_layout);
// 適当にリストビューの設定
ListView listView = (ListView) mSlidingPaneLayout.findViewById(android.R.id.list);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
// 詳細側Fragmentの遷移処理
DetailFragment fragment = new DetailFragment();
// パラメータが必要な場合はsetArgumentsする
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.content, fragment);
ft.addToBackStack(null);
ft.commit();
// パネルを閉じる
if (mSlidingPaneLayout.isSlideable() && mSlidingPaneLayout.isOpen()) {
mSlidingPaneLayout.closePane();
}
}
});
return view;
}
}
이만 마치겠습니다.
네, 간단하죠?
주의점
실시SlidingPaneLayout
에 있어서 매우 큰 주의점이 있다.SlidingPaneLayout
패널의 상태에 따라 메뉴의 표시/숨김을 전환하지 않기 때문에 제어 메뉴의 처리를 직접 작성해야 합니다.
이 패널의 상태, 즉 곡자에 따라 처음 보일 때의 레이아웃ViewTreeObserver.OnGlobalLayoutListener
과 패널 슬라이드를 받을 때의 호출SlidingPaneLayout.PanelSlideListener
을 조합해서 실시해야 한다. @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_slidingpanel, container, false);
mSlidingPaneLayout = (SlidingPaneLayout) view.findViewById(R.id.sliding_pane_layout);
// パネルの状態に応じてメニュー制御を行う
mSlidingPaneLayout.setPanelSlideListener(new SlidingPaneLayout.PanelSlideListener() {
@Override
public void onPanelSlide(View view, float v) {
}
@Override
public void onPanelOpened(View view) {
panelOpened();
}
@Override
public void onPanelClosed(View view) {
panelClosed();
}
});
// 初回のみ、レイアウト状態に応じてメニュー制御を行う必要がある
mSlidingPaneLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@SuppressWarnings("deprecation")
@Override
public void onGlobalLayout() {
if (mSlidingPaneLayout.isSlideable()) {
// パネルがスライド可能な場合、状態に応じてメニュー変更
if (mSlidingPaneLayout.isOpen()) {
panelOpened();
} else {
panelClosed();
}
}
// 初回のみわかれば良いのでリスナー解除
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
mSlidingPaneLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
else
mSlidingPaneLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
// 以下略
}
/**
* パネルが閉じられた時の処理
*/
private void panelClosed() {
// リスト側メニューを無効化、詳細側メニューを有効化
setHasOptionsMenu(false);
if (getChildFragmentManager().findFragmentById(R.id.content) != null) {
getChildFragmentManager().findFragmentById(R.id.content).setHasOptionsMenu(true);
}
}
/**
* パネルが開かれた時の処理
*/
private void panelOpened() {
// リスト側メニューを有効化、詳細側メニューを有効化
setHasOptionsMenu(true);
if (getChildFragmentManager().findFragmentById(R.id.content) != null) {
getChildFragmentManager().findFragmentById(R.id.content).setHasOptionsMenu(false);
}
}
총결산
간단하긴 하지만 메뉴를 사용할 때 한꺼번에 귀찮게 하기는 어렵다.
그럼에도 불구하고 애니메이션화된 다중화면을 디자인할 수 있어서 다행이다.
레이아웃 파일로 멀티플렉스를 하는 게 좋을지 판단하기 어려워요.
Reference
이 문제에 관하여(다중 창 레이아웃을 간단하게 실현하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/nein37/items/d3a5e4b016a1251cfad7
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
우선, 배치는 다음과 같다.
목록 영역과 내용 영역에 각각 지정
android:layout_width
하여 터미널의 너비가 합계 이상인 경우 나란히 표시하고 부족한 경우 슬라이드 디스플레이를 전환할 수 있습니다.내용 영역에 지정
android:layout_weight
을 통해 터미널의 폭이 580dp보다 크면 내용 영역을 공백 부분으로 확장할 수 있습니다.또한 컨텐츠 영역에
android:background
가 지정되어 있지만 슬라이드에 숨겨진 그림자 묘사가 이상하게 변하는 경우가 있으므로 무언가를 지정하는 것이 좋습니다.fragment_slidingpanel.xml
<android.support.v4.widget.SlidingPaneLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@android:id/list"
android:layout_width="280dp"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@+id/content"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@android:color/white" />
</android.support.v4.widget.SlidingPaneLayout>
Fragment 설치는 목록 측면SlidingPaneLayout
측면에만 표시됩니다.자세한 패널의 이동 처리만 쓰고 이동할 때 메뉴 옆의 처리를 닫습니다.
기타 다중 창과 슬라이드 애니메이션 등
SlidingPaneLayout
은 자동으로 진행됩니다.SlidingPaneLayout
와 리스트 패널의 설치가 같다Fragment
는 간소화의 비결이다.SlidingPanelFragment.java
public class SlidingPanelFragment extends Fragment {
SlidingPaneLayout mSlidingPaneLayout;
public SlidingPanelFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_slidingpanel, container, false);
mSlidingPaneLayout = (SlidingPaneLayout) view.findViewById(R.id.sliding_pane_layout);
// 適当にリストビューの設定
ListView listView = (ListView) mSlidingPaneLayout.findViewById(android.R.id.list);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
// 詳細側Fragmentの遷移処理
DetailFragment fragment = new DetailFragment();
// パラメータが必要な場合はsetArgumentsする
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.content, fragment);
ft.addToBackStack(null);
ft.commit();
// パネルを閉じる
if (mSlidingPaneLayout.isSlideable() && mSlidingPaneLayout.isOpen()) {
mSlidingPaneLayout.closePane();
}
}
});
return view;
}
}
이만 마치겠습니다.네, 간단하죠?
주의점
실시SlidingPaneLayout
에 있어서 매우 큰 주의점이 있다.SlidingPaneLayout
패널의 상태에 따라 메뉴의 표시/숨김을 전환하지 않기 때문에 제어 메뉴의 처리를 직접 작성해야 합니다.
이 패널의 상태, 즉 곡자에 따라 처음 보일 때의 레이아웃ViewTreeObserver.OnGlobalLayoutListener
과 패널 슬라이드를 받을 때의 호출SlidingPaneLayout.PanelSlideListener
을 조합해서 실시해야 한다. @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_slidingpanel, container, false);
mSlidingPaneLayout = (SlidingPaneLayout) view.findViewById(R.id.sliding_pane_layout);
// パネルの状態に応じてメニュー制御を行う
mSlidingPaneLayout.setPanelSlideListener(new SlidingPaneLayout.PanelSlideListener() {
@Override
public void onPanelSlide(View view, float v) {
}
@Override
public void onPanelOpened(View view) {
panelOpened();
}
@Override
public void onPanelClosed(View view) {
panelClosed();
}
});
// 初回のみ、レイアウト状態に応じてメニュー制御を行う必要がある
mSlidingPaneLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@SuppressWarnings("deprecation")
@Override
public void onGlobalLayout() {
if (mSlidingPaneLayout.isSlideable()) {
// パネルがスライド可能な場合、状態に応じてメニュー変更
if (mSlidingPaneLayout.isOpen()) {
panelOpened();
} else {
panelClosed();
}
}
// 初回のみわかれば良いのでリスナー解除
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
mSlidingPaneLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
else
mSlidingPaneLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
// 以下略
}
/**
* パネルが閉じられた時の処理
*/
private void panelClosed() {
// リスト側メニューを無効化、詳細側メニューを有効化
setHasOptionsMenu(false);
if (getChildFragmentManager().findFragmentById(R.id.content) != null) {
getChildFragmentManager().findFragmentById(R.id.content).setHasOptionsMenu(true);
}
}
/**
* パネルが開かれた時の処理
*/
private void panelOpened() {
// リスト側メニューを有効化、詳細側メニューを有効化
setHasOptionsMenu(true);
if (getChildFragmentManager().findFragmentById(R.id.content) != null) {
getChildFragmentManager().findFragmentById(R.id.content).setHasOptionsMenu(false);
}
}
총결산
간단하긴 하지만 메뉴를 사용할 때 한꺼번에 귀찮게 하기는 어렵다.
그럼에도 불구하고 애니메이션화된 다중화면을 디자인할 수 있어서 다행이다.
레이아웃 파일로 멀티플렉스를 하는 게 좋을지 판단하기 어려워요.
Reference
이 문제에 관하여(다중 창 레이아웃을 간단하게 실현하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/nein37/items/d3a5e4b016a1251cfad7
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_slidingpanel, container, false);
mSlidingPaneLayout = (SlidingPaneLayout) view.findViewById(R.id.sliding_pane_layout);
// パネルの状態に応じてメニュー制御を行う
mSlidingPaneLayout.setPanelSlideListener(new SlidingPaneLayout.PanelSlideListener() {
@Override
public void onPanelSlide(View view, float v) {
}
@Override
public void onPanelOpened(View view) {
panelOpened();
}
@Override
public void onPanelClosed(View view) {
panelClosed();
}
});
// 初回のみ、レイアウト状態に応じてメニュー制御を行う必要がある
mSlidingPaneLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@SuppressWarnings("deprecation")
@Override
public void onGlobalLayout() {
if (mSlidingPaneLayout.isSlideable()) {
// パネルがスライド可能な場合、状態に応じてメニュー変更
if (mSlidingPaneLayout.isOpen()) {
panelOpened();
} else {
panelClosed();
}
}
// 初回のみわかれば良いのでリスナー解除
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
mSlidingPaneLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
else
mSlidingPaneLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
// 以下略
}
/**
* パネルが閉じられた時の処理
*/
private void panelClosed() {
// リスト側メニューを無効化、詳細側メニューを有効化
setHasOptionsMenu(false);
if (getChildFragmentManager().findFragmentById(R.id.content) != null) {
getChildFragmentManager().findFragmentById(R.id.content).setHasOptionsMenu(true);
}
}
/**
* パネルが開かれた時の処理
*/
private void panelOpened() {
// リスト側メニューを有効化、詳細側メニューを有効化
setHasOptionsMenu(true);
if (getChildFragmentManager().findFragmentById(R.id.content) != null) {
getChildFragmentManager().findFragmentById(R.id.content).setHasOptionsMenu(false);
}
}
간단하긴 하지만 메뉴를 사용할 때 한꺼번에 귀찮게 하기는 어렵다.
그럼에도 불구하고 애니메이션화된 다중화면을 디자인할 수 있어서 다행이다.
레이아웃 파일로 멀티플렉스를 하는 게 좋을지 판단하기 어려워요.
Reference
이 문제에 관하여(다중 창 레이아웃을 간단하게 실현하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/nein37/items/d3a5e4b016a1251cfad7텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)