ฉันจัดการเพื่อสร้างวิธีแก้ปัญหาคล้ายกับที่ Google Play Store ใช้ ลิงก์ไปยังคำตอบดั้งเดิม
กรุณาหา GitHub Repo: ที่นี่
คล้ายกันมากกับรหัสของคุณ แต่เพิ่ม 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 :
อัปเดต (ความเข้ากันได้ Gingerbread):
ตามที่กล่าวไว้ที่นี่อุปกรณ์ Gingerbread กำลังส่งคืน 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: การย้อมสีการหลีกเลี่ยงปัญหา
ตามที่ระบุไว้ในบันทึกย่อ dev จำนวนมาก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
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;
}
หน้าจอการตั้งค่าแบบซ้อน
ผู้คนจำนวนมากกำลังประสบปัญหาเกี่ยวกับการรวมถึง Toolbar ในที่ซ้อนกัน<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
ไม่อนุญาตให้มีการยกระดับและเงาในอุปกรณ์ pre-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'
Android 6.0
ฉันได้ตรวจสอบปัญหาที่ทับซ้อนกันของรายงานและฉันไม่สามารถทำซ้ำปัญหาได้
รหัสเต็มรูปแบบในการใช้งานดังกล่าวผลิตดังต่อไปนี้:
ถ้าฉันหายไปบางอย่างโปรดแจ้งให้เราทราบผ่านrepo นี้และฉันจะตรวจสอบ