{"id":64,"date":"2021-11-04T22:20:50","date_gmt":"2021-11-04T22:20:50","guid":{"rendered":"https:\/\/blogs.oregonstate.edu\/workla\/?p=64"},"modified":"2021-11-04T22:20:50","modified_gmt":"2021-11-04T22:20:50","slug":"creating-a-custom-view-in-android","status":"publish","type":"post","link":"https:\/\/blogs.oregonstate.edu\/workla\/2021\/11\/04\/creating-a-custom-view-in-android\/","title":{"rendered":"Creating a Custom View in Android"},"content":{"rendered":"\n<p>Let\u2019s say you are making a project that has a certain set of views that are often repeated.&nbsp; For example, maybe you are placing a name and address combo in many locations in your project.&nbsp; Currently, if just using the stock views within Android, you may end up repeating the same set of views in your XML files to account for this \u2013 a textview for name, a textview for street address, a text view for city etc.&nbsp; What if, instead, you wanted to simply enter a view for address info and then provide it with the information and it automatically creates and fills in all of the pieces?&nbsp; This is a perfect example where custom views can help keep your project D.R.Y.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"> What are Custom Views? <\/h2>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>A custom view is a view that you design in any way you want by extending another view and then overwriting everything you feel necessary.&nbsp; This custom view can then be used in code, and everything defined in it will be inserted wherever it is used.&nbsp; Maybe a stock dialog isn\u2019t the layout you want for all the dialogs in your project?&nbsp; Create a custom dialog you can then call instead.<\/p>\n\n\n\n<p>Let\u2019s walk through the steps of creating a custom view with an example.&nbsp; I am going to create a custom view that contains a user info.&nbsp; This view could then be used anywhere I want to display my user.&nbsp; In my example, the info I need to display includes a username, user level and a logo.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: Decide what to extend<\/h2>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>You can extend from any view\/layout, but think of picking a view that provides some functionality you may want [1].&nbsp; For example, if you are going to want a card, extend card to start and then customize the corners, elevation, content etc so you don\u2019t have to start from scratch.&nbsp; For my example, I am going to extend a linear layout to hold my stuff, as that functionality is all the functionality I need from my parent class.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: Create layout file<\/h2>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>In your layout file, you specify all the details just like you would if you weren\u2019t going to have a custom view.&nbsp; The benefit to this custom view is that now this will only be in this one place instead of repeated everywhere you want to use it.&nbsp; Here is my very simple example layout file:<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"466\" height=\"864\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4737\/files\/2021\/11\/image-1.jpg\" alt=\"\" class=\"wp-image-65\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4737\/files\/2021\/11\/image-1.jpg 466w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4737\/files\/2021\/11\/image-1-162x300.jpg 162w\" sizes=\"auto, (max-width: 466px) 100vw, 466px\" \/><\/figure>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Step 3: Create a child class extending some view<\/h2>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>In my case, I will create the UserInfoView class and extend linear layout.&nbsp;<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"748\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4737\/files\/2021\/11\/image-2.jpg\" alt=\"\" class=\"wp-image-66\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4737\/files\/2021\/11\/image-2.jpg 624w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4737\/files\/2021\/11\/image-2-250x300.jpg 250w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>Within this class I have basically inflated my custom view\u2019s XML file, and then set up the ability to set the imageview\u2019s image and textviews\u2019 texts in both code or via custom XML attributes.&nbsp; Let\u2019s talk about both of these:<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Step 4a: \u00a0Create Custom attributes<\/h2>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>To create custom attributes, we declare a styleable (customarily this would live in a res\/values\/attrs.xml).&nbsp; Place each attribute name in here and then declare what type you are passing in.&nbsp; For example, the username will be a string and the logoRef will be a reference to a drawable.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"273\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4737\/files\/2021\/11\/image-3.jpg\" alt=\"\" class=\"wp-image-67\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4737\/files\/2021\/11\/image-3.jpg 624w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4737\/files\/2021\/11\/image-3-300x131.jpg 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Next, look in the above picture of my UserInfoView class and note the init function.&nbsp; To access these attributes in our class, we obtain the styled attributes [2].&nbsp; If attributes are not null, then we can get text and resource by referencing the given name from the styleable and assigning those to wherever we are going to use them in our custom view.&nbsp; One last note, when done with your styled attribute access, remember to call .recycle()<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Step 4b: Create variables to dynamically update view in code<\/h2>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The UserInfoView class shows three variables that can be used to dynamically set data for the custom view: username, logo, and level.&nbsp; Custom setters were set up so that when somebody assigns a value to these variables that the resulting textviews and imageview will be updated accordingly.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Step 5: Add custom view to our project<\/h2>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>To add this custom view, we can simply use it like any other view in our resource file.&nbsp; In this example program, we use it twice.&nbsp;<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"469\" height=\"871\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4737\/files\/2021\/11\/iamge-4.jpg\" alt=\"\" class=\"wp-image-68\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4737\/files\/2021\/11\/iamge-4.jpg 469w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4737\/files\/2021\/11\/iamge-4-162x300.jpg 162w\" sizes=\"auto, (max-width: 469px) 100vw, 469px\" \/><\/figure>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The first use just shows the basic implementation, while the second shows the use of the custom XML attributes we set up earlier.&nbsp; Notice that to set the username attribute, all we needed to do was add a line in our custom view that said app:username=\u201d{string resource here}\u201d.&nbsp; The code above from our UserInfoView class access and assigns that value.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Now let\u2019s look at the MainActivity class and see how we can dynamically update the code.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"302\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4737\/files\/2021\/11\/image-5.jpg\" alt=\"\" class=\"wp-image-69\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4737\/files\/2021\/11\/image-5.jpg 624w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4737\/files\/2021\/11\/image-5-300x145.jpg 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Notice for meInfo, we simply find the view, and then have access to the view\u2019s .username, .level, and .logo properties to assign a value.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Result<\/h2>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The result of this code is here:<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"417\" height=\"864\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4737\/files\/2021\/11\/image-6.jpg\" alt=\"\" class=\"wp-image-70\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4737\/files\/2021\/11\/image-6.jpg 417w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4737\/files\/2021\/11\/image-6-145x300.jpg 145w\" sizes=\"auto, (max-width: 417px) 100vw, 417px\" \/><\/figure>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Notice that we got to repeat the set of views with a logo, username and level multiple times without having to copy and paste that set of views in every spot in our main activity layout file.&nbsp; For groups of views that you know you will use a lot, making a custom view for the design can save repeating code and make your code less error prone.&nbsp; And the benefit doesn\u2019t stop there.&nbsp; This also allows you to create your own edittext or textview where you override its normal functionality, create repeated logic-heavy views in one spot, or even a completely unique view when no pre-built view meets your needs [3].&nbsp; Custom views allow you to create a fully custom app.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Sources:<\/h2>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>[1] \u201cCreating a View Class\u201d, Oct 27, 2021. Accessed on: Nov 4, 2021. [Online]. Available: <a href=\"https:\/\/developer.android.com\/training\/custom-views\/create-view\">https:\/\/developer.android.com\/training\/custom-views\/create-view<\/a><\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>[2] Elye, <em>Building Custom Components with Kotlin<\/em>, Medium, May 27, 2017.&nbsp; Accessed on: Nov 4, 2021. [Online] Available: <a href=\"https:\/\/medium.com\/mobile-app-development-publication\/building-custom-component-with-kotlin-fc082678b080\">https:\/\/medium.com\/mobile-app-development-publication\/building-custom-component-with-kotlin-fc082678b080<\/a><\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>[3] \u201cCustom View Components\u201d, Dec 27, 2019. Accessed on: Nov 4, 2021. [Online]. Available: <a href=\"https:\/\/developer.android.com\/guide\/topics\/ui\/custom-components\">https:\/\/developer.android.com\/guide\/topics\/ui\/custom-components<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Let\u2019s say you are making a project that has a certain set of views that are often repeated.&nbsp; For example, maybe you are placing a name and address combo in many locations in your project.&nbsp; Currently, if just using the stock views within Android, you may end up repeating the same set of views in&hellip; <a class=\"more-link\" href=\"https:\/\/blogs.oregonstate.edu\/workla\/2021\/11\/04\/creating-a-custom-view-in-android\/\">Continue reading <span class=\"screen-reader-text\">Creating a Custom View in Android<\/span><\/a><\/p>\n","protected":false},"author":11613,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-64","post","type-post","status-publish","format-standard","hentry","category-uncategorized","entry"],"_links":{"self":[{"href":"https:\/\/blogs.oregonstate.edu\/workla\/wp-json\/wp\/v2\/posts\/64","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.oregonstate.edu\/workla\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.oregonstate.edu\/workla\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/workla\/wp-json\/wp\/v2\/users\/11613"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/workla\/wp-json\/wp\/v2\/comments?post=64"}],"version-history":[{"count":1,"href":"https:\/\/blogs.oregonstate.edu\/workla\/wp-json\/wp\/v2\/posts\/64\/revisions"}],"predecessor-version":[{"id":71,"href":"https:\/\/blogs.oregonstate.edu\/workla\/wp-json\/wp\/v2\/posts\/64\/revisions\/71"}],"wp:attachment":[{"href":"https:\/\/blogs.oregonstate.edu\/workla\/wp-json\/wp\/v2\/media?parent=64"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/workla\/wp-json\/wp\/v2\/categories?post=64"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/workla\/wp-json\/wp\/v2\/tags?post=64"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}