Honeycomb/ICS 中的自定义偏好被破坏

发布于 2024-12-25 11:11:38 字数 4329 浏览 1 评论 0原文

我正在使用一个自定义首选项,其中使用标题、摘要和图标。首选项用于选择一个项目(皮肤、应用程序等),然后它将总结当前的选择。这是正确工作的首选项(顶部)以及我在 Honeycomb/ICS 上的问题:

http://imgur.com/vKPOu

http://imgur.com/EiMBr

正在为首选项留出空间,但即使是默认标题/摘要没有出现,并且项目选择的意图也没有触发。这是首选项布局:

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+android:id/widget_frame"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:gravity="center_vertical"
    android:paddingRight="?android:attr/scrollbarSize">
    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dip"
        android:layout_marginRight="6dip"
        android:layout_marginTop="6dip"
        android:layout_marginBottom="6dip"
        android:layout_weight="1">
        <TextView
            android:id="@+android:id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:singleLine="true"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:ellipsize="marquee"
            android:fadingEdge="horizontal" />
        <TextView
            android:id="@+android:id/summary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@android:id/title"
            android:layout_alignLeft="@android:id/title"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:maxLines="2" />
   </RelativeLayout>
   <ImageView
       android:id="@+id/icon"
       android:layout_width="48dp"
       android:layout_height="48dp"
       android:layout_gravity="center" />
</LinearLayout> 

以及自定义首选项本身:

import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
import android.preference.Preference;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

public class SelectedAppPreference extends Preference {
    private Drawable mIcon;

    public SelectedAppPreference(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        final PackageManager pm = context.getPackageManager();
        String packageName = context.getSharedPreferences("appPrefs", Context.MODE_PRIVATE).getString("selected_app_package", null);

        this.setLayoutResource(R.layout.icon_pref);
        try {
            this.mIcon = pm.getApplicationIcon(packageName);
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }
    }

    public SelectedAppPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        final PackageManager pm = context.getPackageManager();
        String packageName = context.getSharedPreferences("appPrefs", Context.MODE_PRIVATE).getString("selected_app_package", null);

        this.setLayoutResource(R.layout.icon_pref);
        try {
            this.mIcon = pm.getApplicationIcon(packageName);
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onBindView(final View view) {
        super.onBindView(view);

        final ImageView imageView = (ImageView)view.findViewById(R.id.icon);
        if ((imageView != null) && (this.mIcon != null)) {
            imageView.setImageDrawable(this.mIcon);
        }
    }

    public void setIcon(final Drawable icon) {
        if (((icon == null) && (this.mIcon != null)) || ((icon != null) && (!icon.equals(this.mIcon)))) {
            this.mIcon = icon;
            this.notifyChanged();
        }
    }

    public Drawable getIcon() {
        return this.mIcon;
    }
}

首选项本身没有什么太令人兴奋的。我感觉问题出在首选项布局 xml 中,但我不确定到底是什么无法正常工作。我可以确认该首选项在 Android 2.1、2.2 和 2.3 设备上运行良好,但在 3.2 和 4.0 上却遇到了问题。有什么建议吗?

I'm using a custom preference that I use the title, summary, and an icon in. The pref is used to select an item (skin, app, etc.), then the it will summarize the current choice. Here's the preference working correctly (top) and my issue on Honeycomb/ICS:

http://imgur.com/vKPOu

http://imgur.com/EiMBr

Space is being made for the preference, but even the default title/summary aren't showing up, and the intent for item selection isn't firing off either. Here's the preference layout:

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+android:id/widget_frame"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:gravity="center_vertical"
    android:paddingRight="?android:attr/scrollbarSize">
    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dip"
        android:layout_marginRight="6dip"
        android:layout_marginTop="6dip"
        android:layout_marginBottom="6dip"
        android:layout_weight="1">
        <TextView
            android:id="@+android:id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:singleLine="true"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:ellipsize="marquee"
            android:fadingEdge="horizontal" />
        <TextView
            android:id="@+android:id/summary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@android:id/title"
            android:layout_alignLeft="@android:id/title"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:maxLines="2" />
   </RelativeLayout>
   <ImageView
       android:id="@+id/icon"
       android:layout_width="48dp"
       android:layout_height="48dp"
       android:layout_gravity="center" />
</LinearLayout> 

And the custom preference itself:

import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
import android.preference.Preference;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

public class SelectedAppPreference extends Preference {
    private Drawable mIcon;

    public SelectedAppPreference(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        final PackageManager pm = context.getPackageManager();
        String packageName = context.getSharedPreferences("appPrefs", Context.MODE_PRIVATE).getString("selected_app_package", null);

        this.setLayoutResource(R.layout.icon_pref);
        try {
            this.mIcon = pm.getApplicationIcon(packageName);
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }
    }

    public SelectedAppPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        final PackageManager pm = context.getPackageManager();
        String packageName = context.getSharedPreferences("appPrefs", Context.MODE_PRIVATE).getString("selected_app_package", null);

        this.setLayoutResource(R.layout.icon_pref);
        try {
            this.mIcon = pm.getApplicationIcon(packageName);
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onBindView(final View view) {
        super.onBindView(view);

        final ImageView imageView = (ImageView)view.findViewById(R.id.icon);
        if ((imageView != null) && (this.mIcon != null)) {
            imageView.setImageDrawable(this.mIcon);
        }
    }

    public void setIcon(final Drawable icon) {
        if (((icon == null) && (this.mIcon != null)) || ((icon != null) && (!icon.equals(this.mIcon)))) {
            this.mIcon = icon;
            this.notifyChanged();
        }
    }

    public Drawable getIcon() {
        return this.mIcon;
    }
}

Nothing too exciting in the preference itself. I have a feeling that the issue is in the preference layout xml, but I'm not sure what exactly is not working correctly. I can confirm that the preference works fine on Android 2.1, 2.2, and 2.3 devices, and I've had issues on 3.2 and 4.0. Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

标点 2025-01-01 11:11:38

我对第三方自定义首选项也遇到了类似的问题,并通过使小部件框架可见来修复它。默认情况下,它在 ICS 中是不可见的。不知道它如何映射到您的自定义偏好。

// This line was in the original code.
LinearLayout widgetFrameView = ((LinearLayout) mView
                    .findViewById(android.R.id.widget_frame));
...
// This line fixed the visibility issue
widgetFrameView.setVisibility(View.VISIBLE);

还必须重新调整视图,使其与 ICS 控制的其余部分保持一致。

I had similar problem with a third party custom preference and fixed it by making the widget frame visible. It was invisible by default in ICS. Dont' know how it maps to your custom preference.

// This line was in the original code.
LinearLayout widgetFrameView = ((LinearLayout) mView
                    .findViewById(android.R.id.widget_frame));
...
// This line fixed the visibility issue
widgetFrameView.setVisibility(View.VISIBLE);

Also had to realign the view to make it consistent with the rest of ICS controls.

旧人哭 2025-01-01 11:11:38

我修复的第三方自定义首选项取自此站点

https://github.com/attenzione/android-ColorPickerPreference/tree/master/src/net/margaritov/preference/colorpicker

我的代码(在ColorPickerPreference.setPreviewColor()) 看起来像

widgetFrameView.setVisibility(View.VISIBLE);
final boolean preApi14 = android.os.Build.VERSION.SDK_INT < 14;
final int rightPaddingDip = preApi14 ? 8 : 5;

widgetFrameView.setPadding(
                      widgetFrameView.getPaddingLeft(),
                      widgetFrameView.getPaddingTop(),
                      (int)(mDensity * rightPaddingDip),
                      widgetFrameView.getPaddingBottom()
                );

This

float mDensity = getContext().getResources().getDisplayMetrics().density;

的 minSdkVersion = 8 并且没有 targetSdkVersion。如果您将 targetSdkVersion 设置为 14 或更高,您可能需要将“5”更改为其他内容,直到右侧的自定义首选项元素与标准首选项元素(例如复选框)很好地对齐。

The third party custom preference I fixed is taken from this site

https://github.com/attenzione/android-ColorPickerPreference/tree/master/src/net/margaritov/preference/colorpicker

My code (in ColorPickerPreference.setPreviewColor()) looks like

widgetFrameView.setVisibility(View.VISIBLE);
final boolean preApi14 = android.os.Build.VERSION.SDK_INT < 14;
final int rightPaddingDip = preApi14 ? 8 : 5;

widgetFrameView.setPadding(
                      widgetFrameView.getPaddingLeft(),
                      widgetFrameView.getPaddingTop(),
                      (int)(mDensity * rightPaddingDip),
                      widgetFrameView.getPaddingBottom()
                );

where

float mDensity = getContext().getResources().getDisplayMetrics().density;

This is with minSdkVersion = 8 and no targetSdkVersion. If you set targetSdkVersion to 14 or more you may need to change the '5' to something else until the custom preference element on the right aligns nicely with the standard ones (e.g. check boxes).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文