작업 표시 줄 호환성이 지원 라이브러리, 개정판 18에 추가되었습니다. 이제 ActionBarActivity
이전 버전의 Android에서 작업 표시 줄을 사용하여 활동을 작성하는 클래스가 있습니다.
지원 라이브러리에서 작업 표시 줄을 추가하는 방법이 PreferenceActivity
있습니까?
이전에는 ActionBarSherlock을 사용 했으며 SherlockPreferenceActivity
.
작업 표시 줄 호환성이 지원 라이브러리, 개정판 18에 추가되었습니다. 이제 ActionBarActivity
이전 버전의 Android에서 작업 표시 줄을 사용하여 활동을 작성하는 클래스가 있습니다.
지원 라이브러리에서 작업 표시 줄을 추가하는 방법이 PreferenceActivity
있습니까?
이전에는 ActionBarSherlock을 사용 했으며 SherlockPreferenceActivity
.
답변:
편집 : appcompat-v7 22.1.0에서 Google은 AppCompatDelegate 추상 클래스를 대리자로 추가하여 AppCompat의 지원을 모든 활동으로 확장 할 수 있습니다.
다음과 같이 사용하십시오.
...
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.widget.Toolbar;
...
public class SettingsActivity extends PreferenceActivity {
private AppCompatDelegate mDelegate;
@Override
protected void onCreate(Bundle savedInstanceState) {
getDelegate().installViewFactory();
getDelegate().onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
getDelegate().onPostCreate(savedInstanceState);
}
public ActionBar getSupportActionBar() {
return getDelegate().getSupportActionBar();
}
public void setSupportActionBar(@Nullable Toolbar toolbar) {
getDelegate().setSupportActionBar(toolbar);
}
@Override
public MenuInflater getMenuInflater() {
return getDelegate().getMenuInflater();
}
@Override
public void setContentView(@LayoutRes int layoutResID) {
getDelegate().setContentView(layoutResID);
}
@Override
public void setContentView(View view) {
getDelegate().setContentView(view);
}
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
getDelegate().setContentView(view, params);
}
@Override
public void addContentView(View view, ViewGroup.LayoutParams params) {
getDelegate().addContentView(view, params);
}
@Override
protected void onPostResume() {
super.onPostResume();
getDelegate().onPostResume();
}
@Override
protected void onTitleChanged(CharSequence title, int color) {
super.onTitleChanged(title, color);
getDelegate().setTitle(title);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
getDelegate().onConfigurationChanged(newConfig);
}
@Override
protected void onStop() {
super.onStop();
getDelegate().onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
getDelegate().onDestroy();
}
public void invalidateOptionsMenu() {
getDelegate().invalidateOptionsMenu();
}
private AppCompatDelegate getDelegate() {
if (mDelegate == null) {
mDelegate = AppCompatDelegate.create(this, null);
}
return mDelegate;
}
}
더 이상 해킹하지 않습니다. AppCompatPreferenceActivity.java 에서 가져온 코드 입니다.
(ViewGroup) getWindow().getDecorView().getRootView()
현재 AppCompat로는 달성 할 방법이 없습니다. 내부적으로 버그를 열었습니다.
PreferenceActivity
추가 될 것으로 예상 할 때 어떤 아이디어 가 ActionBarCompat
있습니까?
Google Play 스토어에서 사용하는 것과 비슷한 해결 방법을 만들었습니다. 원래 답변으로 연결
자신의 코드와 매우 유사하지만 제목을 설정할 수 있도록 xml을 추가했습니다.
계속 사용 PreferenceActivity
:
settings_toolbar.xml :
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
app:navigationContentDescription="@string/abc_action_bar_up_description"
android:background="?attr/colorPrimary"
app:navigationIcon="?attr/homeAsUpIndicator"
app:title="@string/action_settings"
/>
SettingsActivity.java :
public class SettingsActivity extends PreferenceActivity {
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent();
Toolbar bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false);
root.addView(bar, 0); // insert at top
bar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
}
Result :
here 지적했듯이 Gingerbread Devices는 다음 줄에서 NullPointerException을 반환합니다.
LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent();
SettingsActivity.java :
public class SettingsActivity extends PreferenceActivity {
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
Toolbar bar;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
LinearLayout root = (LinearLayout) findViewById(android.R.id.list).getParent().getParent().getParent();
bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false);
root.addView(bar, 0); // insert at top
} else {
ViewGroup root = (ViewGroup) findViewById(android.R.id.content);
ListView content = (ListView) root.getChildAt(0);
root.removeAllViews();
bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false);
int height;
TypedValue tv = new TypedValue();
if (getTheme().resolveAttribute(R.attr.actionBarSize, tv, true)) {
height = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
}else{
height = bar.getHeight();
}
content.setPadding(0, height, 0, 0);
root.addView(content);
root.addView(bar);
}
bar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
}
위의 문제는 알려주세요!
업데이트 2 : 틴팅 해결 방법
많은 개발 노트에서 지적했듯이 PreferenceActivity
요소 색조를 지원하지 않지만 몇 가지 내부 클래스를 사용하면이를 달성 할 수 있습니다. 이러한 클래스가 제거 될 때까지입니다. (appCompat support-v7 v21.0.3을 사용하여 작동).
다음 가져 오기를 추가하십시오.
import android.support.v7.internal.widget.TintCheckBox;
import android.support.v7.internal.widget.TintCheckedTextView;
import android.support.v7.internal.widget.TintEditText;
import android.support.v7.internal.widget.TintRadioButton;
import android.support.v7.internal.widget.TintSpinner;
그런 다음 onCreateView
메소드를 대체하십시오 .
@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
// Allow super to try and create a view first
final View result = super.onCreateView(name, context, attrs);
if (result != null) {
return result;
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
// If we're running pre-L, we need to 'inject' our tint aware Views in place of the
// standard framework versions
switch (name) {
case "EditText":
return new TintEditText(this, attrs);
case "Spinner":
return new TintSpinner(this, attrs);
case "CheckBox":
return new TintCheckBox(this, attrs);
case "RadioButton":
return new TintRadioButton(this, attrs);
case "CheckedTextView":
return new TintCheckedTextView(this, attrs);
}
}
return null;
}
Result:
AppCompat 22.1에는 새로운 색조 요소가 도입되었으므로 더 이상 마지막 업데이트와 동일한 효과를 얻기 위해 내부 클래스를 사용할 필요가 없습니다. 대신 이것을 따르십시오 (여전히 재정의하십시오 onCreateView
).
@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
// Allow super to try and create a view first
final View result = super.onCreateView(name, context, attrs);
if (result != null) {
return result;
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
// If we're running pre-L, we need to 'inject' our tint aware Views in place of the
// standard framework versions
switch (name) {
case "EditText":
return new AppCompatEditText(this, attrs);
case "Spinner":
return new AppCompatSpinner(this, attrs);
case "CheckBox":
return new AppCompatCheckBox(this, attrs);
case "RadioButton":
return new AppCompatRadioButton(this, attrs);
case "CheckedTextView":
return new AppCompatCheckedTextView(this, attrs);
}
}
return null;
}
필수 환경 설정 화면
많은 사람들이 툴바를 중첩 된 곳에 포함시키는 데 문제가 발생 <PreferenceScreen />
하지만 해결책을 찾았습니다! -많은 시행 착오 끝에!
에 다음을 추가하십시오 SettingsActivity
.
@SuppressWarnings("deprecation")
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
super.onPreferenceTreeClick(preferenceScreen, preference);
// If the user has clicked on a preference screen, set up the screen
if (preference instanceof PreferenceScreen) {
setUpNestedScreen((PreferenceScreen) preference);
}
return false;
}
public void setUpNestedScreen(PreferenceScreen preferenceScreen) {
final Dialog dialog = preferenceScreen.getDialog();
Toolbar bar;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
LinearLayout root = (LinearLayout) dialog.findViewById(android.R.id.list).getParent();
bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false);
root.addView(bar, 0); // insert at top
} else {
ViewGroup root = (ViewGroup) dialog.findViewById(android.R.id.content);
ListView content = (ListView) root.getChildAt(0);
root.removeAllViews();
bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false);
int height;
TypedValue tv = new TypedValue();
if (getTheme().resolveAttribute(R.attr.actionBarSize, tv, true)) {
height = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
}else{
height = bar.getHeight();
}
content.setPadding(0, height, 0, 0);
root.addView(content);
root.addView(bar);
}
bar.setTitle(preferenceScreen.getTitle());
bar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
}
그 이유 PreferenceScreen
는 래퍼 대화 상자를 기반으로하기 때문에 도구 모음을 추가하기 위해 대화 상자 레이아웃을 캡처해야하기 때문입니다.
가져 오기를 디자인하면 Toolbar
v21 이전 장치에서 고도 및 음영을 허용하지 않으므로 고도를 높이려면 Toolbar
다음을 포장해야합니다 AppBarLayout
.
`settings_toolbar.xml :
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
.../>
</android.support.design.widget.AppBarLayout>
build.gradle
파일에 종속성으로 디자인 지원 라이브러리를 추가하는 것을 잊지 마십시오 .
compile 'com.android.support:support-v4:22.2.0'
compile 'com.android.support:appcompat-v7:22.2.0'
compile 'com.android.support:design:22.2.0'
보고 된 겹치는 문제를 조사한 결과 문제를 재현 할 수 없습니다.
위와 같이 사용중인 전체 코드는 다음을 생성합니다.
누락 된 내용이 있으면 이 리포지토리 를 통해 알려 주시면 조사하겠습니다.
:)
PreferenceActivity
엉덩이에 그런 고통이 사용 됩니까 ??? 시간을 절약해야합니다. 정기적 인 활동을하고 수동으로 모든 설정을 선형 레이아웃으로 배치 할 수도 있습니다. uuuu!
support-v4 Fragment를 기반으로 PreferenceFragment 구현을 찾았습니다.
https://github.com/kolavar/android-support-v4-preferencefragment
편집 : 방금 테스트했으며 훌륭하게 작동했습니다!
PreferenceActivity
적어도 나에게는 ABC와의 통합 이 불가능합니다. 나는 찾을 수있는 두 가지 가능성을 시도했지만 아무도 효과가 없었습니다.
ActionBarPreferenceActivity
확장 PreferenceActivity
합니다. 이렇게하면에 의해 제한을받습니다 ActionBarActivityDelegate.createDelegate(ActionBarActivity activity)
. 또한 ActionBar.Callbacks
액세스 할 수없는 것을 구현해야합니다
ActionBarPreferenceActivity
확장 ActionBarActivity
합니다. 이 방법은 완전히 새로운 재 작성 필요 PreferenceActivity
, PreferenceManager
그리고 수 있습니다 PreferenceFragment
당신은 같은 숨겨진 클래스에 액세스해야하는 수단 com.android.internal.util.XmlUtils
구현 DEVS 단지 구글에서 올 수있는이에 대한 해결책을 ActionBarWrapper
모든 활동에 추가 할 수 있습니다.
선호 활동이 정말로 필요한 경우 지금 내 조언은 ActionBarSherlock
입니다.
그러나 여기서 구현했습니다 .
영업 이익은 우리가 넣을 수있는 방법을 알고 싶어 MenuItem
에들 ActionBar
의 PreferenceActivity
안드로이드 지원 라이브러리는 이런 일이 허용하지 않는 버그가 있기 때문에 사전에 벌집을 위해.
목표를 달성하기 위해 이미 제안 된 것보다 훨씬 깨끗한 방법을 찾았습니다 ( Android Docs 에서 찾았습니다 ).
android:parentActivityName
활동의 논리 상위 클래스 이름입니다. 여기서 이름은 해당 요소의 android : name 속성에 지정된 클래스 이름과 일치해야합니다.
시스템은이 속성을 읽고 사용하여 조치 표시 줄에서 위로 단추를 누를 때 시작해야하는 활동을 판별합니다. 시스템은이 정보를 사용하여 TaskStackBuilder를 사용하여 활동의 백 스택을 합성 할 수도 있습니다.
API 레벨 4-16을 지원하기 위해 "android.support.PARENT_ACTIVITY"값을 지정하는 요소를 사용하여 상위 활동을 선언 할 수도 있습니다. 예를 들면 다음과 같습니다.
<activity android:name="com.example.app.ChildActivity" android:label="@string/title_child_activity" android:parentActivityName="com.example.myfirstapp.MainActivity" > <!-- Parent activity meta-data to support API level 4+ --> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.example.app.MainActivity" /> </activity>
이제 일반적으로 할 일을하십시오 onOptionsItemSelected()
. Android Docs의 일부이므로 부작용이 없습니다.
행복한 코딩. :)
Lollipop을 타겟팅하는 경우이 솔루션은 더 이상 작동하지 않습니다. AppCompat를 사용하는 경우이 답변을 찾으십시오.
PreferencesActivity
항목 ActionBar
, 특히 뒤로 버튼 을 넣을 방법이 없다는 것 입니다. 내 대답은 그에 대한 좋은 해결책입니다.
:)
android.app.Actionbar
을 사용하여 얻을 수있었습니다 getActionBar()
. 처음에는 null 값을 반환 한 다음 매니페스트로 이동하여 테마를 다음과 같이 변경했습니다.
android:theme="@style/Theme.AppCompat"
그런 다음 작업 표시 줄을 다시 가질 수있었습니다. 나는 이것이 특정 빌드 레벨에서만 작동한다고 가정합니다. 따라서 빌드 번호를 확인하거나 반환 된 값이 null인지 확인할 수 있습니다.
내가 작업중 인 앱이 ICS/4.0
+ 용이므로 괜찮습니다 .
이제이 문제에 대한 공식 답변이 발표되었습니다. 그것은이다 V7 / V14 기본 설정 지원 라이브러리입니다.
v7 / v14 환경 설정 지원 라이브러리를 사용하는 방법을 참조하십시오 . 그것을 사용하는 방법에 대한 토론.