我创建了一个Custom首选项,它具有以下构造函数
public CoordinatesPreference(Context context, AttributeSet attrs)
{
super(context, attrs);
setLayoutResource(R.layout.coordinates_preference);
}
我有Overriden onCreateView()
因此它会像这样写入日志:
@Override
protected View onCreateView(ViewGroup parent)
{
Log.d("test", "Creating Preference view");
return super.onCreateView(parent);
}
并且我的日志中充满了"Creating Preference view"
消息,这会产生滚动的迟钝感觉,我相信转换视图应该解决这个问题,我看看偏好源代码,如果转换视图为null则onCreateView()
被称为。{/ p>
出于测试目的,我添加了这个方法:
@Override
public View getView(View convertView, ViewGroup parent)
{
if (convertView == null)
{
return super.getView(convertView, parent);
}
return super.getView(convertView, parent);
}
并设置一个断点。我发现几乎总是我的转换视图为空。因此它必须创建一个新视图,为什么会这样?如何改进这一点以避免出现滞后的偏好屏幕?
编辑:更改了onCreate的调用方式,现在它的所有android我只使用setLayoutResource
。但这并没有解决问题...
EDIT2:我已经使用了Debug.StartMethodTracing()
,并且发现因为我怀疑55%的时间花费(当我只是向上和向下滚动时)花费在方法{{ 1 {}当onCreateView()
为空时从getView()
调用。
谢谢,杰森
答案 0 :(得分:3)
我不知道你在这个自定义偏好中实现了什么,但也许超类不知道如何为你的偏好创建一个合适的视图?
来自文档:
protected View onCreateView(ViewGroup 亲本)
自: API级别1创建视图 在这个偏好中显示出来 PreferenceActivity。默认 行为是膨胀主要布局 这个偏好(见 setLayoutResource(INT)。如果改变 这个行为请指定一个 具有ID widget_frame的ViewGroup。使 一定要打电话给 超类的实现。
http://developer.android.com/reference/android/preference/Preference.html
我猜你已经在水平布局上设置了这个id。
现在我正在谈论它,你为什么不在你正在膨胀的布局中包含这个水平布局?
答案 1 :(得分:1)
我不确定您使用的代码是否是准确的测试。我有一个自定义首选项,我只覆盖5个方法,其中三个是构造函数。
public ImageButtonPreference(Context context)
{
this(context, null);
}
public ImageButtonPreference(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
}
public ImageButtonPreference(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
mInflater = LayoutInflater.from(context);
// This is where I pull all of the styleable info from the attrs
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ImageButtonPreference, defStyle, 0);
for(int i = a.getIndexCount(); i >= 0; i--)
{
int attr = a.getIndex(i);
switch (attr)
{
case R.styleable.ImageButtonPreference_logo:
mImageResource = a.getResourceId(attr, mImageResource);
break;
case R.styleable.ImageButtonPreference_button_text:
mButtonText = a.getString(attr);
break;
}
}
}
@Override
protected View onCreateView(ViewGroup parent)
{
View view = mInflater.inflate(R.layout.image_button_preference, parent, false);
return view;
}
@Override
protected void onBindView(View view)
{
super.onBindView(view);
ImageView image = (ImageView)view.findViewById(R.id.Logo);
if(image != null && mImageResource != 0) image.setImageResource(mImageResource);
Button button = (Button)view.findViewById(R.id.ConnectButton);
if(button != null)
{
button.setText(mButtonText);
button.setOnClickListener(mButtonListener);
}
}
我已经从Android Source中逐字逐句提取此代码,因此它应该与其他任何首选项一样快。
答案 2 :(得分:0)
作为更一般的答案,与自定义偏好无关:
使用您发布的代码很难看到,但如果您需要在每次创建视图时提取首选项,那么您所描述的内容将非常缓慢且滞后。即使视图确实存在,您仍然需要设置值,听起来需要来自首选项。 Android偏好读取速度非常慢,因此如果您想获得良好的快速体验,则无法将其与UI创建相关联。
我认为你应该在应用程序中存储首选项(可能在Activity中,或者将Application子类化并存储在那里),以便实现一些简单的缓存。即,当您第一次需要偏好时,从您应用的商店请求它,如果它不在那里,请将其从偏好中拉出来。如果首选项已存储在活动/应用程序中,请使用该值而不要访问prefs。然后,当您写出prefs时,写入商店和首选项。通过这样做,getView()需要创建新视图的频率并不重要,因为可以使用活动/应用程序对象中的副本快速访问首选项,但也可以在未来的首选项中持久存储。
我不知道首选框架是否在某处有一些缓存,但我加载prefs的经验是,如果少数需要加载用户会发现滞后,所以缓存是必不可少的。
答案 3 :(得分:0)
我遇到了这个问题,我追踪到的事实是我在preferences.xml文件和我的Preference子类onCreateView()方法中都设置了布局。当我从preferences.xml中删除布局时,onCreateView()停止多次调用。