I have created a Custom preference which has the following constructor
public CoordinatesPreference(Context context, AttributeSet attrs)
{
super(context, attrs);
setLayoutResource(R.layout.coordinates_preference);
}
And I have Overriden onCreateView()
so it writes to the log like this:
@Override
protected View onCreateView(ViewGroup parent)
{
Log.d("test", "Creating Preference view");
return super.onCreateView(parent);
}
and my log is full of "Creating Preference view"
messages, this creates a laggy feel to scrolling and I believe convert view is supposed to solve this, I had a look at the preference source code and if convert view is null then onCreateView()
is called.
for testing purposes I added this method:
@Override
public View getView(View convertView, ViewGroup parent)
{
if (convertView == null)
{
return super.getView(convertView, parent);
}
return super.getView(convertView, parent);
}
and set a break point. I have found that almost always my convert view is null. and therefore it must create a new view, why is this? and how can I improve this to avoid a laggy preference screen?
EDIT: Changed the way the onCreate is called, now its all android I just use setLayoutResource
. but this does not solve the problem...
EDIT2: I have used Debug.StartMethodTracing()
and have found as I suspected that 55% of the time spend (when I'm just scrolling up and down) is spend on the Inflation of the preference from the method onCreateView()
which is called from getView()
when convertView
is null.
Thanks, Jason
I don't know what have you implemented in this custom preference, but maybe the super class doesn't know how create a proper view to your preference?
From the documentation:
protected View onCreateView (ViewGroup parent)
Since: API Level 1 Creates the View to be shown for this Preference in the PreferenceActivity. The default behavior is to inflate the main layout of this Preference (see setLayoutResource(int). If changing this behavior, please specify a ViewGroup with ID widget_frame. Make sure to call through to the superclass's implementation.
http://developer.android.com/reference/android/preference/Preference.html
I guess you have set that id on the horizontal layout.
Now that I'm talking about it, why don't you include this horizontal layout in the layout that you are inflating?
I am not sure if the code you are using is an accurate test. I have a custom preference and I only override 5 methods and three of them are constructors.
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);
}
}
I have pulled this code, almost verbatim from the Android Source, so it should be just as fast as any other preference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With