Findviewbyid () function usage and simplification in Android development

Source: Internet
Author: User
Tags class definition reflection

Android Findviewbyid () is a very common function, located in the Android.app.Activity package. The function uses the id attribute of the view that we defined in the XML file to get the corresponding view object. Findviewbyid () belongs to API level 1, and the corresponding Android version is android1.0, which shows that the function is available in earlier versions of Android. By the way, Android's current commercially available version and its corresponding API level are as follows:

Android 1.0API Level 1

Android 1.1API Level 2

Android 1.5API Level 3

Android 1.6API Level 4

Android 2.0API Level 5

Android 2.0.1 API Level 6

Android 2.1API Level 7

Android 2.2API Level 8

1. Parameter error: The Findviewbyid parameter is the ID of a view, and if the corresponding ID is not defined in the XML file, the program

Kindly tell you: XXX cannot be resulved. At this point, the supplemental definition is OK.

2. Call layout not specified: Findviewbyid () call is related to the specific layout, the default is the layout in Main.xml, before the function

No layout instructions. However, when we add other layouts in the layout described in Main.xml, we use this function to obtain

To take view from the added layout, you need to add the layout name when called, as follows:

Addlayout.findviewbyid (), if not, the program sometimes compiles without an error, but the runtime

Prompts to encounter an exception and forces the application to close.


3, naming conflict: This error may not be very common, but, if not met, the fierce to come this way, it really makes people a bit Meng.

Oh, I have made such a mistake. Explain that the naming conflict here refers to the classes defined in the current project and

Android provides the same name in the framework, so the current engineering document will give priority to the work

The definition in the process. Of course, when you use the Findviewbyid () function, this error must meet the following conditions:

First, you need to use the ID (defined in XML) in the current project to find the corresponding view object;

The second is: Find the view class name exactly the same as the existing class definition in this project

Three: Two classes with the same name are instantiated with different object types, such as: One is view, the other is activity.

Problem phenomenon:

Is this code familiar? A control more than the page has been repeatedly write such code is not very troublesome?

Workaround:


Customize a method:

Public <T> T $ (int viewid) {
Return (T) Findviewbyid (VIEWID);
}

Then no matter what type of view, directly a $ method is done:


Android Reflection simplifies Findviewbyid.

The little thing in the official case ...

An annotation: Injectview


Import Java.lang.annotation.ElementType;
Import java.lang.annotation.Retention;
Import Java.lang.annotation.RetentionPolicy;
Import Java.lang.annotation.Target;

/**
* Use this annotation to mark the fields of your activity as being injectable.
* <p>
* The {@link Injector} class for more details about this operates.
*/
@Target ({Elementtype.field})
@Retention (Retentionpolicy.runtime)
Public @interface Injectview {
/**
* The resource ID of the View to find and inject.
*/
public int value ();
}

A functional class that is annotated and instantiated by reflection:


Import java.lang.annotation.Annotation;
Import Java.lang.reflect.Field;

Import android.app.Activity;

/**
* Very lightweight form of injection, inspired by roboguice, for injecting common UI elements.
* <p>
* Usage is very simple. In your, define some fields as follows:
*
* <pre class= "code" >
* @InjectView (R.id.fetch_button)
* Private Button Mfetchbutton;
* @InjectView (R.id.submit_button)
* Private Button Msubmitbutton;
* @InjectView (R.id.main_view)
* Private TextView Mtextview;
* </pre>
* <p>
* Then, inside your activity ' s onCreate () method, perform the injection as this:
*
* <pre class= "code" >
* Setcontentview (R.layout.main_layout);
* Injector.get (this). inject ();
* </pre>
* <p>
* The {@link #inject ()} method is for all details of how it works. Note that the fields are
* fetched and assigned at the time with call {@link #inject ()}, consequently to you should does this
* Until after your ' ve called the Setcontentview () method.
*/
Public final class Injector {
Private final activity mactivity;

Private Injector (activity activity) {
Mactivity = activity;
}

/**
* Gets a {@link Injector} capable of injecting fields for the given activity.
*/
public static Injector Get (activity activity) {
Return to new Injector (activity);
}

/**
* Injects all fields this are marked with the {@link Injectview} annotation.
* <p>
* For each field marked with the Injectview annotation
* {@link Activity#findviewbyid (int)} is made, passing in the resource ID stored in the
* Value () method of the Injectview annotation as the int parameter, and the
* 'll be assigned to the field.
*
* @throws illegalstateexception If injection fails, common causes being this you have used
* Invalid ID value, or you haven ' t called Setcontentview () on the Your activity.
*/
public void inject () {
For (Field Field:mActivity.getClass (). Getdeclaredfields ()) {
For (Annotation annotation:field.getAnnotations ()) {
if (Annotation.annotationtype (). Equals (Injectview.class)) {
try {
class<?> FieldType = Field.gettype ();
int idvalue = InjectView.class.cast (annotation). value ();
Field.setaccessible (TRUE);
Object Injectedvalue = Fieldtype.cast (Mactivity.findviewbyid (idvalue));
if (Injectedvalue = = null) {
throw new IllegalStateException ("Findviewbyid" + idvalue
+ ") gave null for" +
Field + ", can ' t inject");
}
Field.set (mactivity, Injectedvalue);
Field.setaccessible (FALSE);
catch (Illegalaccessexception e) {
throw new IllegalStateException (e);
}
}
}
}
}
}

Similar when used:

@InjectView (R.id.gygallery)
02.private Gallery Gallery;
@InjectView (R.id.is_switcher)
04.private Imageswitcher Imageswitcher;
@InjectView (R.id.gygallery)
Private Gallery Gallery;
@InjectView (R.id.is_switcher)
Private Imageswitcher Imageswitcher;

Activity>oncreate () {


Injector.get (this). inject ();//init views

}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.