Setting preference layout and changing the attribute in it

13,498

Solution 1

Try taking a look at the following discussions on imageview. Might help you with your issue.

Android: findViewById of an ImageView (custom adapter)

Android : getting NullPointerException for ImageView imag = (ImageView) findViewById(R.id.image)

Solution 2

After 20 min of hair pulling I found an elegant solution to this problem. First, extend the preference, then override the getView(View convertView, ViewGroup parent) method. My case was this: I had a preference layout with app icon and 2 text views(app name and version). I want to change app version programatically. How do I do this? just take a look below:

public class AboutUsPreference extends Preference {

    public AboutUsPreference(Context context) {
        super(context);
    }

    public AboutUsPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public AboutUsPreference(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public View getView(View convertView, ViewGroup parent) {
        View v = super.getView(convertView, parent);
        ((TextView)v.findViewById(R.id.textView2)).setText(getAppVersion());        
        return v;
    }

    private String getAppVersion(){
        PackageInfo pInfo = null;
        try {
            pInfo = getContext().getPackageManager().getPackageInfo(getContext().getPackageName(), 0);
        } catch (NameNotFoundException e) {
            Log.e(getClass().getName(), e.getMessage(), e);
            return "";
        }

        String version = pInfo.versionName;
        return getContext().getString(R.string.version, version);
    }


}

The solution is this: View v = super.getView(convertView, parent); when overriding getView method. super.getview call will return your layout view.

And my xml preference looks like:

<com.audioRec.android.settings.aboutUs.AboutUsPreference
        android:layout="@layout/about_preference_layout"/>

Solution 3

try getLayoutResource to get the View of the preference and then get your ImageView

Share:
13,498
Nik Chankov
Author by

Nik Chankov

About me Web developer since Y2K Entrepreneur since 2007 Father Technologies CakePHP (since 2006) jQuery (since 2007-2008) PHP, HTML, SQL etc. (as I said since Y2K) AngularJS Laravel Links More about me Twitter account

Updated on June 05, 2022

Comments

  • Nik Chankov
    Nik Chankov about 2 years

    is it possible to access programmatically a layout which is set to a Preference?

    Here is what I have, a very simple project - proof of concept

    The Preference Activity:

    package com.example;
    
    import android.os.Bundle;
    import android.preference.PreferenceActivity;
    import android.util.Log;
    import android.view.View;
    
    public class PreferenceExampleActivity extends PreferenceActivity {
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.preferences);
    
            ImageView v = (ImageView) findViewById(R.id.iconka);
    
        }
    }
    

    The resource XML:

    <?xml version="1.0" encoding="utf-8"?>
    <PreferenceScreen
      xmlns:android="http://schemas.android.com/apk/res/android" 
      android:key="settings">
        <PreferenceCategory 
            android:title="Category Setting Name" 
            android:order="1" 
            android:key="Main">
            <Preference 
                android:order="1" 
                android:title="Setting" 
                android:summary="Setting1" 
                android:layout="@layout/profile_preference_row"
                android:key="profile" />
        </PreferenceCategory>
    </PreferenceScreen>
    

    The custom layout for the Preference:

    <?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="match_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="15dip"
            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:textColor="?android:attr/textColorSecondary"
                android:maxLines="4" />
    
        </RelativeLayout>
        <ImageView
            android:id="@+id/iconka"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            />
    </LinearLayout>
    

    What I want is to be able to access the "iconka" ImageView from the Activity and change the image from there. I am using API 8 (Android 2.2)

    Currently the "v" is null and I don't have any idea why is that.

    A hint will be much appreciated!

    Update - The Solution: Actually, I needed a custom preference which I can modify for my needs. This one is a practical guide how to create your own Custom preference in your project: Android & Amir - Android Preferences See the part when the author creates a custom preference class.

  • Nik Chankov
    Nik Chankov over 12 years
    this method returns an int (Resource) and it's not useful. I believe that I need to use .getView(), but I can't figure out what should I pass as second parameter. If I pass this.getListView() doesn't return me the proper view.
  • Nik Chankov
    Nik Chankov over 12 years
    I am accepting your answer, but it doesn't solve my problem. I realized that I need somehow to get or extend the ListAdapter of the PreferenceActivity in order to reach the view of the node :( Although I still thinking that getView() of the preference could do the job. Just I need to figure out which is the parent parameter.
  • Bryan
    Bryan over 12 years
    I think you need to pass the parent ViewGroup as the second parameter. @Override public View getView(View convertView, ViewGroup parent) { convertView = this.layout == null ? onCreateView(parent) : this.layout; return convertView; }
  • Bryan
    Bryan over 12 years
    I got that example at the following URL, in the comments of the blog. android-journey.blogspot.com/2010/01/…
  • Bryan
    Bryan over 12 years
    There's also some good advice at this URL on whether or not a custom preference layout should be set using a preferenceActivity or instead do it through a Preference class: stackoverflow.com/questions/7830802/…
  • Nick
    Nick about 9 years
    This was genius! Thanks!
  • bgenchel
    bgenchel over 7 years
    What is the convertView and the parent though?
  • Alexandru Circus
    Alexandru Circus over 7 years
    @bgenchel look at the overwritten getView method from my code example
  • bgenchel
    bgenchel over 7 years
    @AlexandruCircus I see what you've written, but this implies to me that if I were to try to actually use that method to get access to the view, I would need to have access to a view, 'ConvertView' already. If I want to address the Preference's view internally, that can't work because I don't have access to a view to pass in.
  • Rahul Sainani
    Rahul Sainani over 6 years
    Nice one, are all the 3 constructors required for this use case? Or just the one with 2 params?