<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Suleiman&apos;s Blog</title><description>Design, Android, and the web.</description><link>https://blog.iamsuleiman.com/</link><item><title>How I use AI to partner on design problems</title><link>https://blog.iamsuleiman.com/how-i-use-ai-to-think-through-design-problems/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/how-i-use-ai-to-think-through-design-problems/</guid><description>A design workflow where AI holds the context and I do the thinking — from brainstorm to prototype.</description><pubDate>Mon, 11 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Working through a complex design problem means holding a lot in my head. Research synthesis, product metrics, a Slack thread with stakeholder feedback, Figma comments, decisions made in the last iteration. Multiply that across iterations, and it&apos;s hard to keep up.&lt;/p&gt;
&lt;p&gt;Most AI tools push toward visual generation. Faster UI, pretty mockups, vibe-coded prototypes. It&apos;s fast, and it looks good. But it skips the hard part. I always thought design was about solving problems.&lt;/p&gt;
&lt;p&gt;So what if AI could help me think through the problem instead? Hold all of the project&apos;s context and surface the right piece at the right moment. Something that compounds context over a project&apos;s life. Like a &lt;a href=&quot;https://practicalpie.com/memory-palace-simple-guide/&quot;&gt;mind palace&lt;/a&gt;?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./how-i-use-ai-to-think-through-design-problems/mind-palace.gif&quot; alt=&quot;Sherlock Holmes from the BBC series navigating his mind palace&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Once set up, I can go from a well-defined problem to a few data-informed code prototypes quickly. Not vibe-coded UI. Concepts grounded in the actual problem and project context. And I&apos;m not using regular AI chat or &lt;a href=&quot;https://claude.com/resources/tutorials/intro-to-projects&quot;&gt;Projects&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&apos;ll walk through it using Beacon — a fictional local discovery app with made-up research, personas, and one design problem: users bouncing before the data loads. The data and examples aren&apos;t real. The setup is. Sample project is on GitHub, linked at the bottom.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Giving AI the full picture&lt;/h2&gt;
&lt;p&gt;Project context is scattered across different documents, tools and people. Research lives in one place, product metrics in another, stakeholder feedback in Slack threads I missed. Every design session starts with manual context reassembly. So I built a memory bank out of it. Then I taught &lt;a href=&quot;https://claude.com/product/claude-code&quot;&gt;Claude Code&lt;/a&gt; to use it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;my-project/
  .claude/           ← skills live here
  data/              ← research synthesis &amp;amp; metrics (I started with this folder!)
  design/            ← per-feature folders (round-1/, round-2/, … for explorations + feedback)
  project-context/   ← frozen project details (PRD, goals, etc.)
  handoffs/          ← eng specs
  prototypes/        ← working HTML prototypes
  design-system/     ← tokens &amp;amp; components
  CLAUDE.md          ← project instructions
  MEMORY.md          ← persistent context index
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt; &lt;a href=&quot;https://claude.com/blog/using-claude-md-files&quot;&gt;customizes Claude Code&lt;/a&gt; for this project. &lt;code&gt;MEMORY.md&lt;/code&gt; is the running index of all context, data, and decisions. Think of it as a table of contents that keeps evolving. When Claude needs information, this file tells it &lt;em&gt;where&lt;/em&gt; to look.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;design-system/&lt;/code&gt; makes prototypes feel like the real product. My setup is simple: &lt;a href=&quot;https://www.designtokens.org/tr/2025.10/format/#introduction&quot;&gt;design tokens&lt;/a&gt; (spacing, color, typography) as CSS variables. The goal at this stage is validating flows and UX, not visual accuracy. I could wire up this project to my design system code, but setup felt time-consuming.&lt;/p&gt;
&lt;p&gt;I store all project information as &lt;a href=&quot;https://www.markdownguide.org/getting-started/&quot;&gt;markdown&lt;/a&gt;. They&apos;re consistently formatted so AI can retrieve it better. Raw notes are fine going in. Claude can help shape them. Anything confidential, I obfuscate first.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./how-i-use-ai-to-think-through-design-problems/aidesignpartner-structured-data-file.png&quot; alt=&quot;Asking AI the status of a project. Using Claud Code via Terminal in Cursor&quot; title=&quot;Asking AI the status of a project. Using Claud Code via Terminal in Cursor&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I run Claude Code via Terminal in &lt;a href=&quot;https://cursor.com/&quot;&gt;Cursor&lt;/a&gt;. Any IDE showing multiple files works (like VS Code). I need to see the files AI touches. Don&apos;t want any hallucinations creeping in!&lt;/p&gt;
&lt;p&gt;The Terminal looks intimidating. But using Claude there feels like regular AI chat with more power. I can open a new Terminal tab and run another Claude instance. Using Claude Code via the desktop app could work too but I haven&apos;t tried it. Recently I&apos;ve been using &lt;a href=&quot;https://www.warp.dev/&quot;&gt;Warp&lt;/a&gt; to manage multiple agents and get notified when they&apos;re done. Pick an approach you&apos;re comfortable with!&lt;/p&gt;
&lt;h2&gt;Automating my process&lt;/h2&gt;
&lt;p&gt;Once the project had all its context, I noticed another problem. I kept re-explaining the same workflows: &quot;Read the ticket, check research, give me three directions&quot; every time. So I automated them with &lt;a href=&quot;https://claude.com/skills&quot;&gt;Skills&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./how-i-use-ai-to-think-through-design-problems/aidesignpartner-skill-explore.png&quot; alt=&quot;Explore calls upon other skills to thread through a design problem with you — from definition to prototypes&quot; title=&quot;Explore calls upon other skills to thread through a design problem with you — from definition to prototypes&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Skills are documented workflows turned into single commands. &lt;a href=&quot;https://github.com/anthropics/skills&quot;&gt;Anthropic skills&lt;/a&gt; and others are worth using, but &lt;a href=&quot;https://claude.com/docs/skills/how-to&quot;&gt;creating custom ones&lt;/a&gt; tuned to my needs worked best. Here&apos;s what I landed on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;explore&lt;/code&gt;: helps go through an entire design iteration. I give it a problem: a ticket, a brief, or statement and it kicks off an iteration, cross-referencing available data and generates code prototypes for each.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;brainstorm&lt;/code&gt;: for working out which directions are worth pursuing&lt;/li&gt;
&lt;li&gt;&lt;code&gt;synthesize&lt;/code&gt;: takes new raw data and integrates it correctly into the project. Also helps connect new findings to existing data.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;prototyping&lt;/code&gt;: builds self-contained code prototypes grounded in the design system.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;design-partner&lt;/code&gt;: highly personalized to how I work. I use it to pressure-test a direction against my own standards and project goals.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Highly recommend taking the time to tweak these skills to your working style, especially &lt;code&gt;design-partner&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Connecting to live data&lt;/h2&gt;
&lt;p&gt;As projects evolve, new context surfaces first in meetings or tools like Slack, Figma or Linear. I&apos;d rather stay immersed in the problem. So I lean on &lt;a href=&quot;https://modelcontextprotocol.io/introduction&quot;&gt;MCPs&lt;/a&gt; (Model Context Protocol) to pull information from these tools. Setup takes time with authentication and permissions. But once running, it stays out of the way.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://linear.app/docs/mcp&quot;&gt;&lt;strong&gt;Linear&lt;/strong&gt;&lt;/a&gt;: When the problem lives in a ticket, I point &lt;code&gt;/explore&lt;/code&gt; at it so Claude can gather context, read the latest activity, and also help keep it updated.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://help.figma.com/hc/en-us/articles/32132100833559-Guide-to-the-Figma-MCP-server&quot;&gt;&lt;strong&gt;Figma&lt;/strong&gt;&lt;/a&gt;: Claude references mocks to generate accurate prototypes. Figma MCP writes to the canvas too which is useful. The more structured the Figma, the better it works. I&apos;ve found great results giving Claude a well-defined, scoped section of mocks versus the entire file link.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.figma-console-mcp.southleft.com/&quot;&gt;&lt;strong&gt;Figma Console MCP&lt;/strong&gt;&lt;/a&gt;: Lets my project learn the design system from Figma libraries instead of wiring up a codebase. Extracts richer layer data than a screenshot. If code extraction isn&apos;t an option, this helps get it from your Figma libraries.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://tools.slack.dev/mcp/&quot;&gt;&lt;strong&gt;Slack&lt;/strong&gt;&lt;/a&gt;: Stakeholder feedback, new decisions, timeline shifts hit Slack before they hit any ticket. Teaching Claude where to look keeps it (and me) current.&lt;/p&gt;
&lt;p&gt;All of these are optional. My project started with none of them. I wanted it working on its own first. MCPs came later, as I noticed patterns in my workflow worth automating. More connections means more things that can break so there&apos;s a balance.&lt;/p&gt;
&lt;h2&gt;In practice&lt;/h2&gt;
&lt;p&gt;One &lt;code&gt;/explore&lt;/code&gt; run is the start, not the finish. Most problems take several iterations. I&apos;ve noticed that the more clear I am, the fewer back and forth I have with AI.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./how-i-use-ai-to-think-through-design-problems/workflow-diagram.jpg&quot; alt=&quot;/explore chains brainstorm, synthesize, and prototyping skills into one command. One prompt kicks off a full iteration.&quot; title=&quot;/explore chains brainstorm, synthesize, and prototyping skills into one command. One prompt kicks off a full iteration.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;AI surfaces directions I use as starting points. Those proposals are far from sharing or shipping. So I have it surface relevant data points. But I steer what it needs to build. I&apos;ll take over with Figma mocks if needed to help it along.&lt;/p&gt;
&lt;p&gt;A typical session. Some commands are skills, some natural language. I talk to it like a collaborator. No re-explaining. It knows the project.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Where did I leave this project? What should I focus on next?

**/explore** the loading states problem

**/design-partner** evaluate the latest loading states solutions

**/synthesize** stakeholder feedback for revision 2: [raw feedback copy-pasted]

My latest iteration for loading states is complete. Post an update.
(it&apos;ll send a Slack message and Linear comment if MCP works)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Between commands is the actual design work. Sketching, reasoning, spec docs, forming a point of view before I bring Claude back in. This may even mean quick mocks in Figma. &lt;code&gt;/design-partner&lt;/code&gt; pressure-tests my thinking against the problem.&lt;/p&gt;
&lt;p&gt;Once I lock in directions, Claude builds them as code prototypes. Rough on purpose. To align on direction is the goal, not polish. Before anything goes to the team, I validate it against the original problem statement (&lt;code&gt;/design-partner&lt;/code&gt; can help).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./how-i-use-ai-to-think-through-design-problems/aidesignpartner-critique.png&quot; alt=&quot;A session where Claude helps evaluate proposals against existing data and goals&quot; title=&quot;A session where Claude helps evaluate proposals against existing data and goals&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; I always check the AI&apos;s sources. It knows to pull only from existing project data but can still hallucinate. When it cites research to justify a decision, I verify the source.&lt;/p&gt;
&lt;h2&gt;Handoff&lt;/h2&gt;
&lt;p&gt;Once aligned on a prototype, I design Figma mocks for key moments in the flow. Then I write a spec describing the flow: the steps, with Figma frames for the key ones.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./how-i-use-ai-to-think-through-design-problems/aidesignpartner-handoff.gif&quot; alt=&quot;Once the spec is written, Claude has an anchor to generate different outputs from it — high-fidelity prototype, journey map, or implementation plan&quot; title=&quot;Once the spec is written, Claude has an anchor to generate different outputs from it — high-fidelity prototype, journey map, or implementation plan&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Writing out the solution is also context for AI. It becomes the anchor for everything else. Claude can use it to build a high-fidelity prototype, write a journey map, generate an implementation plan for code. It&apos;s also what stops it from hallucinating, especially with complex flows.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;What changed&lt;/h2&gt;
&lt;p&gt;I stopped starting over. Every session picked up where the last one left off with decisions, dead ends, all of it. I could go from a well-defined problem to clickable prototypes fast. Context switching dropped. I could stay in the problem.&lt;/p&gt;
&lt;p&gt;Code prototypes changed the feedback dynamic. Unlike static Figma mocks, they weren&apos;t polished and yet that helped. People stopped picking at visual details and started talking about UX. That&apos;s the conversation I want earlier. Bad ideas die faster too, before I&apos;ve invested much.&lt;/p&gt;
&lt;p&gt;I track decisions per round in the &lt;code&gt;design/&lt;/code&gt; folder. No more digging through Figma comment threads to remember why we made a call three weeks ago. Syncing stakeholders stopped feeling like project management. Claude reads the Linear tickets, Slack threads, and latest research. I don&apos;t manually summarize. It already knows.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./how-i-use-ai-to-think-through-design-problems/aidesignpartner-design-feedback.png&quot; alt=&quot;The design folder&apos;s round-by-round subfolders open in an IDE, showing a stakeholder-feedback summary for one round&quot; title=&quot;Summarizing every round or iteration to inform future explorations&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The longer the project ran, the more useful it got. Early decisions became context for later ones.&lt;/p&gt;
&lt;h2&gt;Where this could go next&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Prototyping with code components.&lt;/strong&gt; Once I have a spec, rough prototype, and key Figma frames, Claude writes an implementation plan. I give that to my codebase and it builds a &lt;a href=&quot;https://storybook.js.org/&quot;&gt;Storybook&lt;/a&gt; prototype using the design system. Real code that my engineers could use. I&apos;ve had a fair amount of success with this. &lt;a href=&quot;https://www.anthropic.com/news/claude-design-anthropic-labs&quot;&gt;Claude Design&lt;/a&gt; might make it easier but haven&apos;t spent enough time with it yet.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Proactive context maintenance:&lt;/strong&gt; Claude is already connected to Linear, Slack, and Figma. Right now I manually feed it updates. I&apos;ve started with a &lt;code&gt;/tidy&lt;/code&gt; skill for cleanup and maintenance, but the next step is surfacing a diff: &quot;here&apos;s what&apos;s new since you were last here.&quot; New ticket comments, a Slack thread with an eng constraint, an updated Figma frame. The biggest tax in this setup is keeping context fresh. This would make it passive.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Post-ship feedback loop:&lt;/strong&gt; The cycle ends at handoff. If I connected analytics, Claude could compare live performance against the original goals. &quot;Bounce during load dropped from 38% to 22% after the receipt pattern shipped.&quot; That closes the loop. I&apos;d know which design decisions worked without pulling dashboards.&lt;/p&gt;
&lt;h2&gt;Caveats&lt;/h2&gt;
&lt;p&gt;There&apos;s quite a few, I won&apos;t lie. But the benefits far outweigh the cons for me to even complain.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Upfront investment is real.&lt;/strong&gt; Organizing project context takes time. I built it piece by piece. The structure is both powerful and fragile. Claude helps maintain it, but I must know what goes in. Incorrect or stale data meant hallucinated outputs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It doesn&apos;t replace thinking.&lt;/strong&gt; The project&apos;s greatest strength is recall and synthesis, not outsourced judgment. Claude does the synthesis work: retrieves the research, matches patterns, frames the initial tradeoffs. I do the design thinking. I&apos;ve never shipped a direction without reshaping it because often times its suggestions can be quite terrible. But it does offer a good starting point.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Complex concepts need structured input.&lt;/strong&gt; A 12-step prototype from a written prompt alone will create drift. Key states mocked in Figma plus a spec document keep AI&apos;s output anchored.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It amplifies blind spots.&lt;/strong&gt; If my research only covers one persona, every recommendation cites that same source. It makes gaps obvious.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Context grows faster than it compresses.&lt;/strong&gt; As a project runs longer, the memory bank grows: more rounds, more decisions, more data files. At some point there&apos;s too much for a session to hold cleanly. I manage it by archiving old rounds, keeping &lt;code&gt;MEMORY.md&lt;/code&gt; lean, starting new chats often (&lt;code&gt;/clear&lt;/code&gt; and &lt;code&gt;/compact&lt;/code&gt; were my friends).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prototype sharing feels rudimentary.&lt;/strong&gt; The prototypes were interactive and fast to get feedback on. My team was super into it. But sharing a zip file isn&apos;t an elegant Figma link. No annotated comments or canvas sometimes made it tricky to gauge feedback via Slack or Linear comments.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Knowing when to take over.&lt;/strong&gt; Sometimes it works flawlessly that my jaw drops. It one-shots my intent perfectly. But sometimes it won&apos;t get the simplest of things right, despite my constant prompts and prayers to the AI gods. That gets tiring. AI gets me 80% of the way. Then I jump to Figma to take it to completion. Otherwise, it&apos;s diminishing returns. It&apos;s also why I&apos;m not chasing high-fidelity concepts with AI (yet).&lt;/p&gt;
&lt;h2&gt;Closing thoughts&lt;/h2&gt;
&lt;p&gt;At two months in (at the time of writing), I&apos;m still finding the edges. But long enough to see it work well. Engineering and product were already moving faster. This is how I can keep pace where AI handles the recall, I handle the judgment.&lt;/p&gt;
&lt;p&gt;I didn&apos;t need AI to crank out pretty UI. I needed it to hold more so I could think clearer. That&apos;s what this does, most of the time.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Starter kit&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Try it yourself on GitHub:&lt;/strong&gt; &lt;a href=&quot;https://github.com/Suleiman19/ai-design-buddy&quot;&gt;github.com/Suleiman19/ai-design-buddy&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/sample&lt;/code&gt; has Beacon pre-loaded with fake data, research, and skills. Good place to explore before committing to your own setup.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;/explore&lt;/code&gt; on result cards to see a full iteration kick off.&lt;/li&gt;
&lt;li&gt;Starting fresh on your own project? Delete &lt;code&gt;/sample&lt;/code&gt; first.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&apos;s early and opinionated. Expect it to change.&lt;/p&gt;
&lt;p&gt;Building something similar or approaching this differently? I&apos;d love to hear about it! Reach out on &lt;a href=&quot;https://www.linkedin.com/in/suleiman-shakir/&quot;&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Framer X For Design - 5 Reasons Why I Switched</title><link>https://blog.iamsuleiman.com/framer-x-design-tool/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/framer-x-design-tool/</guid><description>As a developer turned designer, I have always been fascinated with ways to close the gap between design and development. Recently, I stumbled upon Fra</description><pubDate>Tue, 26 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As a developer turned designer, I have always been fascinated with ways to close the gap between design and development. Recently, I stumbled upon Framer X. After using it for quite a while, I’m convinced that it is a powerful new design tool that closes that gap considerably and encourages tighter collaboration.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
This is not a sponsored post. I haven&apos;t been paid by Framer to write this. All opinions are purely based on my personal experiences with the tool. Moreover, this isn&apos;t a hate post for other design tools (each one excels in its own right).&lt;/p&gt;
&lt;h2&gt;Design tools of the past&lt;/h2&gt;
&lt;p&gt;I have been an avid Sketch user for over 6 years now. However, for prototyping, I always found Framer JS more suited. Yes, the old Framer Classic that scared almost every designer (including me) which required writing code.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./framer-x-design-tool/design-tool-framer-classic.png&quot; alt=&quot;&quot; title=&quot;The interface for Framer Classic or Framer JS. Source - [classic.framer.com](https://classic.framer.com/guides/prototype/)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now, at the time, for logic-based complex prototyping, this was the tool for the job. Framer JS used &lt;a href=&quot;https://coffeescript.org/&quot;&gt;CoffeeScript&lt;/a&gt;, a preprocessor that was friendly and simpler to write so I braved and jumped right in.&lt;/p&gt;
&lt;p&gt;However, despite that, it was so time-consuming to build something in Framer JS that it was my last resort for prototyping. It still didn’t replace my daily design tool yet.&lt;/p&gt;
&lt;p&gt;Sometime later, along came &lt;a href=&quot;https://principleformac.com/&quot;&gt;Principle&lt;/a&gt;. A simple, timeline-based interaction design tool. Given its ease of use, I had quickly forgotten Framer.&lt;/p&gt;
&lt;p&gt;Fast forward to 2019 and I didn’t see Framer JS around anymore. Instead, it was Framer X and everything about it seemed different.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;What is Framer X?&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Framer X is a smart interaction design tool for realistic prototypes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./framer-x-design-tool/new-framer-x-web-landing-page.png&quot; alt=&quot;&quot; title=&quot;The new Framer X (website) — [framer.com](https://www.framer.com/)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Framer X is a complete overhaul with a low entry barrier for designers. Unlike previous versions, I could do everything I could I Sketch (and perhaps more!) without writing a single line of code. Designing and prototyping weren&apos;t two different modes. I found myself seamlessly doing both together. Moreover, there was a slew of features unheard of that highly piqued my curiosity. I had to use it myself to see what the hype was about.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you are a designer who can code or a coder that can design, Framer X will be your very best friend.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.usejournal.com/framer-x-to-future-or-not-to-future-7d83ce1421d6&quot;&gt;John Traver | Framer X: to future or not to future&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;Game-Changing Framer X Features&lt;/h2&gt;
&lt;p&gt;In this article, I’ll show you a comparison between common tasks I’d do in Sketch which, trust me, is similar in almost every other major tool (yes, Figma and XD) and how Framer X handles the same. Hopefully, towards the end of this article, you’re as excited as I am to jump into this new hybrid tool.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./framer-x-design-tool/framer-x-ui-dark-mode.png&quot; alt=&quot;&quot; title=&quot;Framer X interface allows a Day or Night Mode&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So without further delay, here are some of the reasons why I switched to Framer X.&lt;/p&gt;
&lt;h3&gt;Responsive Design For Real&lt;/h3&gt;
&lt;p&gt;To clarify, responsive design in practice (as a designer) is the ability to create and set up on elements on canvas to resize in specific ways across different screen sizes.&lt;/p&gt;
&lt;p&gt;Sketch mimics a simplified version of &lt;a href=&quot;https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/&quot;&gt;Xcode’s AutoLayout&lt;/a&gt;. This feature (of using constraint pins) is familiar across other tools too.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./framer-x-design-tool/xcode-sketch-constraint-pins-auto-layout.png&quot; alt=&quot;&quot; title=&quot;Constraints pins — Xcode uses Auto-Layout (left), Sketch uses resizing pins (right)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;However, I find some quirks with this in Sketch.&lt;/p&gt;
&lt;p&gt;For any element to be resizable, I need to MANUALLY setup every constraint! Moreover, oftentimes, I care about setting constraint values over the specific width or height of an element. For example, if I’m designing a list on iOS. I don’t care about the width of the list itself. What’s more important is that the list maintains a 20px (&lt;a href=&quot;https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/adaptivity-and-layout/&quot;&gt;safe area guides&lt;/a&gt;) margins on either side. For that, I’ll have to recalculate the list’s width itself to get 20px margins on either side.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/framer-x-design-tool/sketch-constraints-manual-calc.gif&quot; alt=&quot;&quot; title=&quot;Here&apos;s an example of how I set explicit constraints in Sketch&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now, Sketch experts might argue that I could use dummy rectangles, rulers or the Anima plugin to space without pixel calculation. That&apos;s workable, but not efficient.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Here&apos;s how Framer X does Responsive Design&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One word — &quot;&lt;strong&gt;automatic&lt;/strong&gt;&quot;.&lt;/p&gt;
&lt;p&gt;Based on how elements are positioned in your Artboard or “Frame” (no, it’s not a pun), Framer will automatically set up constraint pins. In other words, your mocks are responsive by default!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/framer-x-design-tool/framer-x-automatic-constraint-pins-1.gif&quot; alt=&quot;&quot; title=&quot;When you draw elements, Framer automatically pins constraints for you.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Notice how I didn&apos;t explicitly set any width for that rectangle. No manual math. Just set constraint values, Framer automatically pins them based on its position.&lt;/p&gt;
&lt;p&gt;The automatic constraint pins are a HUGE time-saver, allowing me to design with speed.&lt;/p&gt;
&lt;p&gt;If you look at how responsive design in front-end development, setting specific constraint values over specific element values is the norm. For example, when setting a fluid grid, you would declare the margins around each grid item, but let the screen width dictate the size of the grid item itself. Framer uses a similar approach that feels more familiar to use and powerful.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./framer-x-design-tool/framer-x-testimonial.png&quot; alt=&quot;&quot; title=&quot;Testimonial as seen on [framer.com](https://www.framer.com/design/)&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Frames over layers&lt;/h3&gt;
&lt;p&gt;I was confused with the concept of Frames vs Layers first. Traditionally, layers represent individual elements in our Artboards. You could also group them. But groups weren&apos;t layers themselves. This was my understanding with Sketch (no quarrels here). It was a nice way to organize and understand how to build mocks.&lt;/p&gt;
&lt;p&gt;Things in Framer are different. While the Layers panel exists, each &quot;layer&quot; in Framer is actually a &lt;em&gt;Frame&lt;/em&gt; (no pun intended). &lt;a href=&quot;https://help.figma.com/hc/en-us/articles/360041539473-Frames-in-Figma&quot;&gt;Figma folks may feel right at home here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./framer-x-design-tool/framer-layers-frames.png&quot; alt=&quot;&quot; title=&quot;Concept of nesting Frames in Framer&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Each Frame is an empty container that can house other Frames or elements. You can drag and drop other elements inside this Frame. Doing so makes that Frame the automatic parent of those elements. In fact, your &quot;Artboard&quot; is also a Frame.&lt;/p&gt;
&lt;p&gt;This is similar to &lt;code&gt;div&lt;/code&gt; tags in HTML. Each &lt;code&gt;&amp;lt;div/&amp;gt;&lt;/code&gt; can nest child elements. Furthermore, this parent &lt;code&gt;div&lt;/code&gt; container’s properties can affect it’s children as well.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;READ&lt;/strong&gt;&lt;br /&gt;
CSS-Tricks clearly explains the &lt;a href=&quot;https://css-tricks.com/the-css-box-model/&quot;&gt;CSS Box Model&lt;/a&gt; and how that applies to (web) design.&lt;/p&gt;
&lt;p&gt;Initially, this skewed my mental model of how ‘layers’ worked and I struggled. However, over time, this felt natural and more flexible.&lt;/p&gt;
&lt;p&gt;I couldn&apos;t figure out how to best explain why in words. So I made a video for you instead. In this video, I design a simple card in Sketch and then the same in Framer.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/MdsHs1KpWnY&quot;&gt;Watch on YouTube&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Workflow differences in Sketch and Framer&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Previously, I had to draw dummy, invisible rectangles to act as (fake) containers for my elements and then group them. This definitely was NOT ideal! Framer allows you to use Frames as containers for your elements which considerably reduces layer complexity.&lt;/p&gt;
&lt;h3&gt;Stacks&lt;/h3&gt;
&lt;p&gt;Stacks are what &lt;a href=&quot;https://css-tricks.com/snippets/css/a-guide-to-flexbox/&quot;&gt;Flexbox&lt;/a&gt; is in web-development (CSS).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In Framer, Stacks are good for expressing truly fluid layouts. It can automate things such as distribution and alignment.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.framer.com/support/using-framer-x/layout-tools/&quot;&gt;Learn more about Stacks&lt;/a&gt; from Framer&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In Sketch, this functionality doesn’t 100% exist, or in any other tool for that matter. I can somewhat mimic the same with &lt;a href=&quot;https://www.sketch.com/features/smart-layout&quot;&gt;Sketch&apos;s Smart Layout&lt;/a&gt; or the Anima plugin, but it isn&apos;t truly &quot;fluid&quot;.&lt;/p&gt;
&lt;p&gt;However, the Stacks feature in Framer is much more powerful. You start by drawing a Stack and then throw elements inside it. Later, you can configure the Stack’s properties such as orientation, how items should be distributed, and spacing between individual items.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/framer-x-design-tool/framer-x-stacks.gif&quot; alt=&quot;&quot; title=&quot;Stacks in Framer — Creating dynamic, fluid layouts with speed&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This feature opens up powerful possibilities for responsive layouts such as navigation bars, drawers, lists, and grids to name a few. All of these become very easy to make and closer to the real thing.&lt;/p&gt;
&lt;h3&gt;Prototyping in Framer X&lt;/h3&gt;
&lt;p&gt;Traditionally, I always found myself in two distinct modes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Design - where I design all the mocks and its variants (states) for prototyping flow&lt;/li&gt;
&lt;li&gt;Prototype - I take a pass at all my mocks and add in hotspots and links&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In Framer, I am designing and prototyping in parallel. The experience here feels very seamless. You can build a click-through prototype in Framer without writing any code.&lt;/p&gt;
&lt;p&gt;For things like drawers, modals, and more, I don&apos;t find myself redesigning (or copy-pasting) screens. I only design those elements I need for the transition.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/framer-x-design-tool/framer-x-prototyping.gif&quot; alt=&quot;&quot; title=&quot;Framer X — Prototyping&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LEARN MORE&lt;/strong&gt;: &lt;a href=&quot;https://www.framer.com/learn/course/create-a-click-through-prototype/&quot;&gt;Simple click-through prototyping in Framer X&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Logic via code&lt;/h3&gt;
&lt;p&gt;Framer X allows you can take literally ANY element on the canvas and introduce behavior. Remember I mentioned that Framer X is React powered. Be it simple animations, complex interactions, or logic, it is possible.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Every Framer project is a Web project.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;However, I’ll admit this involved me having to learn basic &lt;a href=&quot;https://reactjs.org/docs/getting-started.html&quot;&gt;React&lt;/a&gt;. Luckily, Framer X uses &lt;a href=&quot;https://www.typescriptlang.org/&quot;&gt;TypeScript&lt;/a&gt;, which made writing &lt;a href=&quot;https://reactjs.org/docs/introducing-jsx.html&quot;&gt;JSX&lt;/a&gt; syntax MUCH easier.&lt;/p&gt;
&lt;p&gt;If I want to do things like show a button click? No problem. Show an alert on button click? Sure!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/framer-x-design-tool/framer-button-animation-code-1.gif&quot; alt=&quot;&quot; title=&quot;Simple button interaction with Framer&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Here’s a quick example of how I’d write some code to animate a button on hover and click. I simply have to write a function and then tell my button on canvas to use it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./framer-x-design-tool/framer-button-logic-code-react-1.png&quot; alt=&quot;&quot; title=&quot;Connecting code overrides to a button in Framer X&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This example barely scratches the surface. You can do complex scroll interactions, logic-based prototypes, pulling data via APIs, using real front-end components, and more. But I&apos;m going to keep it simple for now. If you&apos;re interested, the &lt;a href=&quot;https://www.framer.com/learn/&quot;&gt;Framer 101 Crash Course&lt;/a&gt; is the best place to start.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Designing for the future&lt;/h2&gt;
&lt;p&gt;It’s been well over a couple of months since I’ve started using Framer X. While it feels different from tools we&apos;re typically used to, I found Framer more dynamic and powerful. Framer’s tools allow me to communicate my work with high levels of fidelity that wasn’t possible before.&lt;/p&gt;
&lt;p&gt;While those are great benefits, to avoid a biased opinion, it’s important to document its downsides.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Framer X Disadvantages&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Framer&apos;s tools, while more intuitive have an initial learning curve&lt;/li&gt;
&lt;li&gt;To take full advantage of Framer, you&apos;ll have to touch code (and learn React)&lt;/li&gt;
&lt;li&gt;You can achieve extremely high fidelity with Framer - clearly define how much detail is needed in advance&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To end on a more positive note, and to recap, here’s why Framer became my main, go-to design tool.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Framer X Advantages&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Automatic Responsive Design&lt;/li&gt;
&lt;li&gt;Frames and Stacks are powerful tools for responsive design&lt;/li&gt;
&lt;li&gt;Prototyping feels natural and can be used interchangeably when designing (over being a different “mode”)&lt;/li&gt;
&lt;li&gt;Intuitive prototyping without having to duplicate Artboards for UI changes/states&lt;/li&gt;
&lt;li&gt;Use real, interactive components in design&lt;/li&gt;
&lt;li&gt;Framer projects are web projects (you can literally Inspect Element your UI)&lt;/li&gt;
&lt;li&gt;Ability to add logic with code&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Not ready to switch yet?&lt;/strong&gt;&lt;br /&gt;
No problem! Framer X allows you to copy-paste your design elements directly from Sketch/Figma. I did this for a good while until I was confident to fully switch.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;READ&lt;/strong&gt;&lt;br /&gt;
&lt;a href=&quot;https://www.smashingmagazine.com/2019/06/start-using-sketch-framer-x/&quot;&gt;How to start using Sketch and Framer X&lt;/a&gt; — &lt;a href=&quot;http://smashingmagazine.com&quot;&gt;smashingmagazine.com&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;An Exciting Future Ahead&lt;/h3&gt;
&lt;p&gt;Framer X is an interesting and hybrid tool that sits at the intersection of design and development. If you are an engineer who can design or a designer who can code, I highly recommend giving Framer a try. Moreover, Framer is coming to the web this year, which has me excited about all the ways we could improve collaboration.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;&lt;br /&gt;
&lt;a href=&quot;https://www.framer.com/&quot;&gt;Framer Web&lt;/a&gt; is out and now includes a Free plan&lt;/p&gt;
&lt;p&gt;What are your thoughts on the new Framer? Have you tried it already?&lt;/p&gt;
</content:encoded></item><item><title>Build your UX Portfolio from Scratch – Choosing a Web Stack</title><link>https://blog.iamsuleiman.com/build-ux-portfolio-web-stack/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/build-ux-portfolio-web-stack/</guid><description>Choosing to hand-code your UX portfolio can be an ambitious, yet daunting task. Your portfolio website is perhaps the most important avenue to display</description><pubDate>Wed, 07 Aug 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Choosing to hand-code your UX portfolio can be an ambitious, yet daunting task. Your portfolio website is perhaps the most important avenue to display your experience, skills, and values as a designer.&lt;/p&gt;
&lt;p&gt;With that said, you want to put your best foot forward. Having complete control in how you do this is what development (hand-coding) can offer albeit at the cost of time and increased effort.&lt;/p&gt;
&lt;p&gt;A majority of that time could go into choosing the right set of tools for web development. Especially, when there’s a multitude of options to choose from that do similar things. It is important to choose tools that are not only easy to understand but speed up our workflow.&lt;/p&gt;
&lt;p&gt;Even then, making a choice and then sticking with it can be hard, especially when you discover a blocker later down the road.&lt;/p&gt;
&lt;p&gt;That’s what I’m here to help you with.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Welcome to Part 3 of the ‘Build your UX Portfolio from Scratch‘ series!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In this part, I’ll help you look at different available web technologies, their pros, and cons and finally help you decide the right toolset to develop your UX portfolio.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Developing your UX portfolio consumes considerable time and effort. But it grants you complete  freedom and control over how you want to showcase yourself, making the trade-off worth it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-web-stack/web_developer.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Previously in &lt;a href=&quot;https://blog.iamsuleiman.com/build-ux-portfolio-design/&quot;&gt;Part 2&lt;/a&gt;, we designed our UX portfolio by going through the entire design process. By this point, I assume you have a UX portfolio website design ready to go for development. If not, I strongly suggest reading &lt;a href=&quot;https://blog.iamsuleiman.com/build-ux-portfolio-design/&quot;&gt;Part 2&lt;/a&gt; - It includes a lot of resources to inspire you and how to effectively design your portfolio.&lt;/p&gt;
&lt;p&gt;New to the Build your UX portfolio series? Start with &lt;a href=&quot;https://blog.iamsuleiman.com/build-ux-portfolio-getting-started/&quot;&gt;Part 1&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Build your UX Portfolio Series&lt;/strong&gt;&lt;br /&gt;
This tutorial is broken up into several parts:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/build-ux-portfolio-getting-started/&quot;&gt;Part 1: Getting Started&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://blog.iamsuleiman.com/build-ux-portfolio-design/&quot;&gt;Part 2: Design&lt;/a&gt;&lt;br /&gt;
&lt;strong&gt;Part 3: Choosing A Web Stack&lt;/strong&gt;&lt;br /&gt;
Part 4: Setting Up Your System To Start Development &lt;em&gt;(Coming Soon)&lt;/em&gt;&lt;br /&gt;
Part 5: Understanding Your Project Environment &lt;em&gt;(Coming Soon)&lt;/em&gt;&lt;br /&gt;
Part 6: Getting Dirty With Code &lt;em&gt;(Coming Soon)&lt;/em&gt;&lt;br /&gt;
Part 7: Optimizing Your Portfolio For Speed &lt;em&gt;(Coming Soon)&lt;/em&gt;&lt;br /&gt;
Part 8: Launch your Website &lt;em&gt;(Coming Soon)&lt;/em&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Overview&lt;/h2&gt;
&lt;p&gt;Typically, I&apos;d call this section &apos;Getting Started&apos;, but that&apos;s &lt;a href=&quot;https://blog.iamsuleiman.com/build-ux-portfolio-getting-started/&quot;&gt;Part 1&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When starting to look for web tools, it helps to fully know exactly what you need in terms of features and functionality. Before we actually put our ‘research expertise’ to use on Google, remember this rule of thumb&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Prefer popular tools that have a huge community behind it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Why you ask?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Online help (Stack Overflow) when you’re stuck, not knowing how to do something&lt;/li&gt;
&lt;li&gt;Strong tool development support with plans for the future&lt;/li&gt;
&lt;li&gt;A low number of bugs (no bugs is near impossible) with workarounds&lt;/li&gt;
&lt;li&gt;A large number of other tools that will work nicely with it, sometimes offering very easy plug and play options&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So keep this in mind when you&apos;re trying to find something suitable for your needs.&lt;/p&gt;
&lt;p&gt;With that said, what do we actually need?&lt;/p&gt;
&lt;h3&gt;Type of Tools Needed for your UX Portfolio&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-web-stack/undraw_JavaScript_frameworks_8qpc.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In a broad sense, we need 3 types of tools:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;a Text Editor&lt;/li&gt;
&lt;li&gt;a front-end (CSS) Web Framework&lt;/li&gt;
&lt;li&gt;a Build System&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Don’t panic if any of this doesn’t make sense to you. I’ll explain below what each one is, why we need them and a curated selection of each kind to choose from.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
None of the tools I recommend are promotions or sponsored content that I’m trying to sell to you. They are all my personal opinions which I say from experience.&lt;/p&gt;
&lt;h4&gt;1. Text Editor&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-web-stack/ux-portfolio-web-stack-front-end-tools.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;We briefly looked into text editors in &lt;a href=&quot;https://blog.iamsuleiman.com/build-ux-portfolio-getting-started/&quot;&gt;Part1 - Getting Started&lt;/a&gt;. Even so, I’ll briefly cover them here.&lt;/p&gt;
&lt;p&gt;Text editors can help us code faster with powerful features such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;auto-complete&lt;/li&gt;
&lt;li&gt;syntax highlighting&lt;/li&gt;
&lt;li&gt;useful find and replace features&lt;/li&gt;
&lt;li&gt;extensibility (ability to add more features via plugins)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, our focus on our UX portfolio website is going to be a text editor. Something lightweight and fast. Remember, nothing over the top!&lt;/p&gt;
&lt;p&gt;Here are the 3 most popular ones.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-web-stack/sublime_text_3_logo.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sublime Text 3&lt;/strong&gt;&lt;br /&gt;
A sophisticated text-editor built for speed and extensibility&lt;/p&gt;
&lt;p&gt;- Super fast to use&lt;br /&gt;
- free trial forever&lt;br /&gt;
- Plugins&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://webdesign.tutsplus.com/tutorials/useful-shortcuts-for-a-faster-workflow-in-sublime-text-3--cms-22185&quot;&gt;Useful Shortcuts&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-web-stack/atom_editor_logo.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Atom&lt;/strong&gt;&lt;br /&gt;
Free, open-source text editor by GitHub&lt;/p&gt;
&lt;p&gt;- Easy to use and great UI&lt;br /&gt;
- Packages&lt;br /&gt;
- GitHub integration&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.sitepoint.com/12-favorite-atom-tips-and-shortcuts-to-improve-your-workflow/&quot;&gt;Useful Shortcuts&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-web-stack/visual-studio-logo-windows.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Visual Studio (VS)&lt;/strong&gt;&lt;br /&gt;
A fast and powerful IDE by Microsoft&lt;/p&gt;
&lt;p&gt;- powerful IDE&lt;br /&gt;
- great refactoring tools&lt;br /&gt;
- advanced features and complexity&lt;/p&gt;
&lt;p&gt;While Visual Studio is popular, it is an IDE that might be overkill.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
Text Editors are NOT IDEs (Integrated Development Environment)! Both are two very different things. Text editors are more lightweight while IDEs are more robust including more powerful and complex features.&lt;/p&gt;
&lt;p&gt;The Sublime Text VS Atom debate happens a lot around the internet. There isn’t anything that one has that the other doesn’t that could be a possible deal-breaker.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;READ&lt;/strong&gt;&lt;br /&gt;
&lt;a href=&quot;https://jaxenter.com/ides-vs-text-editor-148936.html&quot;&gt;IDEs VS Text Editors – When to use what?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I have used both extensively and can personally say that it all comes down to personal preference. I used Sublime Text before and recently have gravitated more towards Atom because I like the interface for managing my packages.&lt;/p&gt;
&lt;p&gt;To build this specific iteration of my UX portfolio, I used Atom. For the previous iteration, I used Sublime Text. I can’t really say much for VS Code. While it’s powerful, I also find it fairly complex to use for a project of this simple scale and complexity.&lt;/p&gt;
&lt;p&gt;If you have trouble deciding, here’s &lt;a href=&quot;https://stackshare.io/stackups/atom-vs-sublime-text-vs-visual-studio-code&quot;&gt;a comparison of all 3&lt;/a&gt; which help give you perspective.&lt;/p&gt;
&lt;p&gt;So go ahead, try and pick one which you like. I promise that your choice won’t be a hinderance for this tutorial.&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;2. Front-end Web Framework&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-web-stack/under_constructions_2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;To put it in very plain words, it is a CSS framework that’ll help you speed up your web development (front-end).&lt;/p&gt;
&lt;p&gt;A good framework includes provides you with the following features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A responsive grid with strong support for ‘mobile-first’ design&lt;/li&gt;
&lt;li&gt;Collection of customizable components (buttons, forms, tabs, tables, etc) to use in your website&lt;/li&gt;
&lt;li&gt;In-built functionality for adding interactivity&lt;/li&gt;
&lt;li&gt;All in all, easy to use, extend and modify&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Keeping that in mind, here are some popular frameworks.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-web-stack/ux-portfolio-web-dev-bootstrap-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bootstrap 4&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is the most popular front-end component library for building responsive projects.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://getbootstrap.com&quot;&gt;Get Bootstrap 4&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-web-stack/ux-portfolio-web-dev-uikit.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UIkit&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A modular, lightweight CSS framework with many useful components for small-scale projects.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://getuikit.com&quot;&gt;Get UIkit&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-web-stack/ux-portfolio-web-dev-materialize-css.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Materialize CSS&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A CSS framework that&apos;s based on Google&apos;s Material Design&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://materializecss.com&quot;&gt;Get Materialize CSS&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-web-stack/ux-portfolio-web-dev-skeleton-css.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Skeleton&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Extremely simple and lightweight responsive framework (just 200 lines of code).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Limited in functionality. Use with caution!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://getskeleton.com&quot;&gt;Get Skeleton&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Some other frameworks worth looking into include:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://foundation.zurb.com&quot;&gt;Foundation&lt;/a&gt;&lt;/strong&gt;&lt;br /&gt;
Most advanced responsive framework. Best suited for large-scale, complex enterprise-level projects.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://semantic-ui.com&quot;&gt;**Semantic UI&lt;br /&gt;
**&lt;/a&gt;A framework designed with ease of use and natural naming of classes&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bulma.io&quot;&gt;&lt;strong&gt;Bulma&lt;/strong&gt;&lt;/a&gt;&lt;br /&gt;
A (relatively new) modern, elegant, free, open-source framework that&apos;s quick to pick up&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://purecss.io&quot;&gt;**Pure CSS&lt;br /&gt;
**&lt;/a&gt;A framework with a small footprint. Includes responsive CSS modules for quick use&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Again, picking the right one here is more of personal preference. But keep this in mind when choosing a framework you like.&lt;/p&gt;
&lt;p&gt;The more robust a framework is (lots of components, features, etc.),  it comes with great support but larger will be the learning curve and complexity of use. While simpler, smaller frameworks can be quick to pick up and use, they can quickly become limiting and may not have everything you need and with lesser community support.&lt;/p&gt;
&lt;p&gt;In plain words, by community support, I mean that when you get stuck at some point, you most likely could be on your own since Stack Overflow might not have an answer for you.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
Pick whatever you like. But take your time and think carefully on your choice because unlike Text Editors, swapping out CSS Frameworks can be a pain!&lt;/p&gt;
&lt;p&gt;But don’t fret because, if you’re unsure of what to choose, pick Bootstrap.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RECOMMENDED FRAMEWORK&lt;/strong&gt;&lt;br /&gt;
For this tutorial, I will be using &lt;a href=&quot;https://getbootstrap.com&quot;&gt;&lt;/a&gt;&lt;strong&gt;&lt;a href=&quot;https://getbootstrap.com&quot;&gt;Bootstrap 4&lt;/a&gt;&lt;/strong&gt;, the most popular and versatile framework. It is the most safe option which is quick to use which offsets the slightly higher learning curve.&lt;/p&gt;
&lt;p&gt;If you’re thinking ahead, you might worry about things like, Bootstrap is large and includes lots of things that I won’t use. That is true, but there are ways to fix that (relatively simple) which I will address in future parts.&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;3. Build System&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-web-stack/undraw_processing_qj6a.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;A Build System tool is a task runner that can help automate tasks that you otherwise would do manually. With a little bit of setup, the pay off is huge in terms of speed and time gain.&lt;/p&gt;
&lt;p&gt;A build system can manage many things, saving you from performing repetitive tasks manually. Some of them include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;dependency management&lt;/li&gt;
&lt;li&gt;watch your files for changes to automatically update changes&lt;/li&gt;
&lt;li&gt;combining multiple stylesheets, js into one&lt;/li&gt;
&lt;li&gt;automatically minifying/compressing source files and images&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here are some of the popular build systems.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-web-stack/build-system-tool-gulp.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Gulp&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A popular, simple build system (task runner) to automate and enhance your workflow&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://gulpjs.com&quot;&gt;Get Gulp&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-web-stack/build-system-tool-webpack.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Webpack&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A popular bundler with powerful features.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Might require more complexity to configure!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://webpack.js.org&quot;&gt;Get Webpack&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-web-stack/build-system-tool-browserify.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Browserify&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A module-based bundler that allows you to use Node.JS bundles directly in the browser&lt;/p&gt;
&lt;p&gt;Get Browserify&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.toptal.com/front-end/webpack-browserify-gulp-which-is-better&quot;&gt;Gulp VS Webpack VS Browserify - which is better?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Some other tools include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://gruntjs.com&quot;&gt;Grunt&lt;/a&gt;&lt;/strong&gt;&lt;br /&gt;
A Javascript task runner&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bower.io&quot;&gt;&lt;strong&gt;Bower&lt;/strong&gt;&lt;/a&gt;&lt;br /&gt;
a package manager for the web&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;**Tl;DR&lt;br /&gt;
**Gulp is a task runner which is simple enough to configure and quick to get us up and running. I will be using &lt;strong&gt;&lt;a href=&quot;https://gulpjs.com&quot;&gt;Gulp&lt;/a&gt;&lt;/strong&gt;, keeping in mind its speed and simplicity.&lt;/p&gt;
&lt;p&gt;I&apos;ve found Gulp easy to use, so if you’re using the same, then I assure you that you’re in safe hands!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;strong&gt;Final Tools in your Arsenal&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;To recap, we looked at the 3 different kinds of tools we need. Then we did a deep dive at each type and saw various available options.&lt;/p&gt;
&lt;p&gt;Then, for this tutorial series I mentioned that I will be using:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://atom.io&quot;&gt;&lt;strong&gt;Atom&lt;/strong&gt;&lt;/a&gt; as my text editor&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://getbootstrap.com&quot;&gt;&lt;strong&gt;Bootstrap&lt;/strong&gt;&lt;/a&gt; as my front-end framework&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gulpjs.com&quot;&gt;&lt;strong&gt;Gulp&lt;/strong&gt;&lt;/a&gt; for my build system&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-web-stack/ux-portfolio-final-tools-web-stack.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In this article, I hope I&apos;ve given you an overview of the different kinds of tools we need and a taste of the different choices available in each.&lt;/p&gt;
&lt;p&gt;While I could&apos;ve simply said we&apos;re going to use these 3 tools right from the start. But I believe it&apos;s fair to lay out what&apos;s available to us, understand the options, analyze them and then make a meaningful choice.&lt;/p&gt;
&lt;h3&gt;Next Steps&lt;/h3&gt;
&lt;p&gt;Now that you have downloaded what you need, you&apos;re probably wondering &quot;Now how the heck do I set everything up and actually begin coding my UX portfolio?&quot;&lt;/p&gt;
&lt;p&gt;That&apos;s exactly what I&apos;m going to cover in the next part. In Part 4, I&apos;ll walk you through setting up all these tools to play nicely with each other and show you how to use them!&lt;/p&gt;
&lt;p&gt;In the meantime, if you liked what you read, share this article with others who are developing their own UX portfolio. If you have any questions or thoughts, let me know in the comments below.&lt;/p&gt;
&lt;p&gt;Lastly, don’t forget to subscribe below to know first when Part 4 is out!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Part 4: Configuring your Web Stack (Coming Soon…)&lt;/em&gt;&lt;/p&gt;
</content:encoded></item><item><title>Build your UX Portfolio From Scratch – Design</title><link>https://blog.iamsuleiman.com/build-ux-portfolio-design/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/build-ux-portfolio-design/</guid><description>Designing your own UX portfolio can give you an edge to stand out from the crowd. By choosing to design it yourself, it is an opportunity to showcase </description><pubDate>Tue, 16 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Designing your own UX portfolio can give you an edge to stand out from the crowd. By choosing to design it yourself, it is an opportunity to showcase your brand and who you are.&lt;/p&gt;
&lt;p&gt;By being original and unique, your portfolio will be memorable. So don&apos;t copy a theme or someone else&apos;s design. You don&apos;t want your UX portfolio to come off as a common template or worse, a rip-off.&lt;/p&gt;
&lt;p&gt;Welcome to &lt;strong&gt;Part 2&lt;/strong&gt; of the &apos;&lt;em&gt;Build your UX Portfolio from Scratch&lt;/em&gt;&apos; series!&lt;/p&gt;
&lt;p&gt;In this part, we&apos;ll look at how to approach the design phase. From brainstorming ideas on how might we design our portfolio to building high-fidelity screens and then preparing to handoff for development.&lt;/p&gt;
&lt;p&gt;Previously in &lt;a href=&quot;https://blog.iamsuleiman.com/build-ux-portfolio-getting-started/&quot;&gt;Part 1&lt;/a&gt;, I gave you an overview on what this series is going to be about. It covers a lot of things right from a website name to all the various tools we&apos;ll use from design to development. If you haven&apos;t read it yet, I highly encourage you to &lt;a href=&quot;https://blog.iamsuleiman.com/build-ux-portfolio-getting-started/&quot;&gt;start with Part 1&lt;/a&gt; first!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Design Process&lt;/h2&gt;
&lt;p&gt;It always helps to start with a plan or a road-map. To begin with, think of your portfolio as a design problem - Just as you&apos;d tackle as any other design challenge.&lt;/p&gt;
&lt;p&gt;But before we even decide on a design plan and anything else, ask yourself this.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why do you need a Portfolio? Who are its Users?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;
You are not the user.&lt;/p&gt;
&lt;p&gt;Do you need a portfolio to attract new clients? Or is it to help you land a new role? Think about it&apos;s use-case and who the target users are. For instance, if you need a portfolio to help you get a job, then the users might be recruiters and hiring managers.&lt;/p&gt;
&lt;p&gt;Looking at it this way will help decide what want to show on your portfolio and how to present it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Treat your UX Portfolio as a design problem&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yes, I&apos;m asking you to UX your portfolio!&lt;/p&gt;
&lt;p&gt;Asking yourself these questions early on will give you perspective. It will allow you to design with your target audience in mind.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;READ&lt;/strong&gt;&lt;br /&gt;
&lt;a href=&quot;https://www.invisionapp.com/inside-design/considering-the-user-of-your-ux-portfolio/&quot;&gt;Considering the user of your UX portfolio&lt;/a&gt; – Sarah Doody, Inside Design by InVision&lt;/p&gt;
&lt;p&gt;Here&apos;s the design process we&apos;re going to follow, right from hand-sketching and all the way to  publishing our finished website.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-design/ux_portfolio_design_process.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This image could potentially be misleading since it appears to be linear. But design is never linear. Rather, it is iterative. So while you design your portfolio, you can iterate across these steps multiple times until you reach a design that is satisfactory (within reasonable time of course).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Quick Navigation&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#brainstorm&quot;&gt;Brainstorm&lt;/a&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#paper-sketching&quot;&gt;Paper Sketching&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#wireframing&quot;&gt;Wireframing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#medium-fidelity&quot;&gt;Medium-fidelity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#high-fidelity&quot;&gt;High-fidelity&lt;/a&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#final-designs&quot;&gt;Final Designs&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#test-feedback&quot;&gt;Test for Feedback (Optional)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#handoff&quot;&gt;Development Handoff&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#takeaways&quot;&gt;Takeaways&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Brainstorm - by finding inspiration&lt;/h2&gt;
&lt;p&gt;Whether this is the first time you&apos;re making your portfolio or not, you can always learn by learning from what other&apos;s have made.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.bestfolios.com/tags/Google?page=1&amp;amp;type=portfolio&quot;&gt;Bestfolios has a great collection of UX portfolio examples&lt;/a&gt;. They are portfolios of designers in companies like Google, Facebook, Spotify and more!&lt;/p&gt;
&lt;p&gt;If you&apos;re not sure on what to include in your portfolio yet, this can be a powerful starting point. Looking at how the industry approaches it can give you an idea on WHAT to include and HOW.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-design/bestfolios-portfolios.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Inspiring collection of UX/UI portfolios - &lt;strong&gt;&lt;a href=&quot;https://www.bestfolios.com/home&quot;&gt;bestfolios.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;INSPIRATION&lt;/strong&gt;&lt;br /&gt;
&lt;a href=&quot;https://medium.com/bestfolios/10-student-portfolios-done-right-2019-7d4fa0f033d&quot;&gt;10 Student Portfolios Done Right – Bestfolios&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Make note of patterns&lt;/h3&gt;
&lt;p&gt;Once, you&apos;ve browsed through many portfolios, you&apos;ll start to notice a common pattern - A compelling hero section, focus on projects, and an about me page at the least.&lt;/p&gt;
&lt;p&gt;While visually, there might be variations, here&apos;s what a common portfolio structure looks like.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-design/ux_portfolio_patterns_details.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Common Layout/Components in a UX Portfolio Website&lt;/p&gt;
&lt;p&gt;Remember, this is YOUR portfolio. So while you look for inspiration, use it to nail the essentials down. But infuse it with your personality to make it unique to you!&lt;/p&gt;
&lt;h3&gt;Paper Sketching&lt;/h3&gt;
&lt;p&gt;Now that you&apos;ve seen a couple of portfolio, you should have a pretty good idea on how you might want yours to look like. While that thought is fresh on your mind, put it down on paper.&lt;/p&gt;
&lt;p&gt;Doesn&apos;t matter how it looks. Don&apos;t worry about fonts, colors and other visual specifics. Just dump everything that&apos;s on your mind onto a paper. Believe me, in this way, you&apos;ll be able to brainstorm over ideas MUCH faster.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
There can be a strong tendency to directly jump into code. Resisting that temptation allows you to be more open and flexible to ideas for your portfolio.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Paper sketching allows you to ideate at the speed of thought.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here are some rough sketches I came up with on the things I wanted to do for my portfolio. Be sure to keep this handy. It works as a great reference point from designing to development!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-design/ux-portfolio-paper-sketches.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Initial paper sketching to brainstorm ideas for my UX Portfolio.&lt;/p&gt;
&lt;p&gt;Notice that I&apos;ve also scribbled a lot of notes around my screens. They&apos;ll be a useful guide for the next design phase.&lt;/p&gt;
&lt;p&gt;The focus here was on two key screens - the Home and About page. You might wonder, &quot;What about the case studies?&quot;. While that is by far the most important, in this scenario, content and presentation overthrow the design of the page itself.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
For my case studies, I chose to write them on Medium as I was more concerned with content rather than the visual design of the page.&lt;/p&gt;
&lt;p&gt;However, if you wish to keep your case studies in-house, I strongly encourage you to attempt brainstorming them too&lt;/p&gt;
&lt;p&gt;If you&apos;re doing a redesign, make sure you only change those aspects of your portfolio that needs improvement. This could be something you&apos;ve been wanting to improvise, or you&apos;ve received feedback from users.&lt;/p&gt;
&lt;p&gt;If you&apos;re unsure, look at your analytics data or previous user tests if any. I know this might be a little overkill. But testing is key to thoughtful design. I&apos;ll cover more on testing further in this article.&lt;/p&gt;
&lt;p&gt;The paper sketches are a crucial starting point for your UX portfolio. Think of it as a visual map that will guide us in building our wireframes and high-fidelity. Next, we&apos;ll use this to build our wireframes.&lt;/p&gt;
&lt;h2&gt;Wireframing&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;A &lt;strong&gt;wireframe&lt;/strong&gt; is a blueprint. A visual guide that represents the skeleton framework of a website&lt;/p&gt;
&lt;p&gt;Wikipedia&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-design/ux_portfolio_undraw_wireframe.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;By this point, you&apos;d know the elements to include in your portfolio. Your rough paper sketches are a handy guide to what those are.&lt;/p&gt;
&lt;p&gt;In wireframing, think about the skeleton or structure of your portfolio. All those elements you wish to include, think about how you want to place them and where.&lt;/p&gt;
&lt;p&gt;Here are my wireframes. At this point, you could jump into a design software of your choice to design wireframes. For this entire tutorial series, I will be using &lt;a href=&quot;https://www.sketch.com&quot;&gt;Sketch&lt;/a&gt; (Mac-only). For Windows, the alternatives are &lt;a href=&quot;https://www.figma.com&quot;&gt;Figma&lt;/a&gt; and &lt;a href=&quot;https://www.adobe.com/products/xd.html&quot;&gt;Adobe XD&lt;/a&gt;. I&apos;ve gone over this in &lt;a href=&quot;https://blog.iamsuleiman.com/build-ux-portfolio-getting-started/#design-tools&quot;&gt;Part 1&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-design/ux-portfolio-wireframe-home.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Home&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-design/ux-portfolio-wireframe-about.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;About&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;
This is a good time to think about the portfolio copy such as the headline, subtitle, your about me page, etc. It doesn&apos;t have to be set in stone at this point, but at least, form a rough idea of what you want to say.&lt;/p&gt;
&lt;p&gt;Continue to be flexible with ideation at this point. It allows your mind to be open to new ideas. You&apos;ll notice there are a few changes I&apos;ve made to the design in the wireframes compared to the paper sketches.&lt;/p&gt;
&lt;h2&gt;Medium-Fidelity&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Medium-Fidelity designs include the interactions &amp;amp; navigation possibilities of an application.&lt;/p&gt;
&lt;p&gt;Definition from &lt;a href=&quot;https://www.d-labs.com/en/services-and-methods/medium-fidelity-prototyping.html&quot;&gt;d-labs.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Alright, I tried my best to get you a definition that makes sense. But turns out, I didn&apos;t understand the technical verbage here either. So let me try to explain what medium-fidelity means, in simple terms.&lt;/p&gt;
&lt;p&gt;Medium-fidelity includes what your final UX portfolio contains such as layout elements, its navigation and text.&lt;/p&gt;
&lt;p&gt;In other words, your navigation links, what your button is supposed to say, your headlines, subtitles, about me. All content needs to be finalized at this phase.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-design/ux_portfolio_undraw_medium-fidelity.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CAUTION&lt;/strong&gt;&lt;br /&gt;
At this phase, do not, I repeat, DO NOT focus on colors, font styles or any other aspect of visual design&lt;/p&gt;
&lt;p&gt;Medium-fidelity does NOT mean visual design. Focus on the structure of your UX portfolio. How does your design hold up with the final copy in place?&lt;/p&gt;
&lt;p&gt;Keep your medium-fidelity monotone (grayscale). Doing so will keep your focus on structuring your portfolio rather than visual details such as colors and typography.&lt;/p&gt;
&lt;p&gt;To design in medium-fidelity, you can use your existing wireframes to build upon. Leverage Symbols to upgrade the fidelity of your existing components.&lt;/p&gt;
&lt;p&gt;The fact that you aren&apos;t worrying about visuals will allow you focus on the bigger picture. You won&apos;t be bothered with petty things such as &quot;Should the button be rounded by 2 or 3px?&quot; or &quot;Should the spacing be 40 or 48px&quot;.&lt;/p&gt;
&lt;p&gt;Here&apos;s how my medium fidelity designs look like.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-design/ux-portfolio-medium-fidelity-home.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Home&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-design/ux-portfolio-medium-fidelity-about.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;About&lt;/p&gt;
&lt;p&gt;I know that some things could be improved here, such as spacing. But as I&apos;ve previously said, the focus should be on layout structure, final copy and how that plays well with your design.&lt;/p&gt;
&lt;p&gt;With that said, we now move on to the most fun and visual part of building your UX portfolio.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Design for High-Fidelity&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;High-fidelity designs appear and function as similar as possible to the actual product that will ship.&lt;/p&gt;
&lt;p&gt;Nick Babich, &lt;a href=&quot;https://theblog.adobe.com/prototyping-difference-low-fidelity-high-fidelity-prototypes-use/&quot;&gt;Adobe Blog&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-design/ux_portfolio_undraw_high-fidelity.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This is the phase where you&apos;re going to be spending a bulk of your time. After all, it is designing how your UX portfolio will actually look like on the browser! Define the visual style - colors, typography, spacing, etc.&lt;/p&gt;
&lt;p&gt;Before you let loose your creativity, keeping these tips in mind can make things easier.&lt;/p&gt;
&lt;h3&gt;3 Key things to remember&lt;/h3&gt;
&lt;h4&gt;1. &lt;strong&gt;Create a styleguide to build faster&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;A simple styleguide for colors, typography and basic elements can help you design faster.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-design/styleguide.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;
If you have a front-end framework you wish to use, they might have a Sketch styleguide for you to download. If they do, I highly encourage you to use that to jumpstart your design.&lt;/p&gt;
&lt;p&gt;For my portfolio, I decided to use &lt;a href=&quot;https://getbootstrap.com&quot;&gt;Bootstrap 4&lt;/a&gt; (a very popular front-end web framework). Luckily they had a &lt;a href=&quot;https://www.forumone.com/ideas/what-is-design-system/&quot;&gt;design system&lt;/a&gt; for Sketch. I quickly adapted that to my branding and jumpstarted my design. I&apos;ll cover more about front-end frameworks when we get into development.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bootstrap 4 Design System&lt;/strong&gt;&lt;br /&gt;
If you plan on using Bootstrap 4, you can &lt;a href=&quot;https://www.sketchappsources.com/free-source/3135-bootstrap4-design-system-sketch-freebie-resource.html&quot;&gt;grab the design kit Sketch file for free from sketchappresources.com&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;2. Consistency is key&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Your portfolio is your brand. Make sure it has one voice that echoes in unison across your whole site. Be it colors, type or even the content - keep it consistent.&lt;/p&gt;
&lt;h4&gt;3. Showcase who you are as a designer&lt;/h4&gt;
&lt;p&gt;While your portfolio is largely about your work (case studies), it also about demonstrating who you are as a designer and your beliefs.&lt;/p&gt;
&lt;p&gt;So ensure your portfolio echoes your thoughts and beliefs in unison. For example, as a designer, I believe in clear, simple experiences that are minimally designed. Hence, my portfolio too is designed to reflect the same.&lt;/p&gt;
&lt;p&gt;However, if I said that and then had a portfolio designed over the top with flash of colors and animation, that would be confusing right?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt; – **Don&apos;t aim for perfection&lt;br /&gt;
**Aiming for &apos;that perfect design&apos; will waste a LOT of your time. graudally improve upon it. Don&apos;t get stuck trying to make it perfect (because there is no such thing).&lt;/p&gt;
&lt;h3&gt;Final Designs&lt;/h3&gt;
&lt;p&gt;Here&apos;s the final designs for my portfolio.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-design/ux-portfolio-high-fidelity-home.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Home&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-design/ux-portfolio-high-fidelity-about.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;About Me&lt;/p&gt;
&lt;p&gt;If you&apos;re interested in getting the high-fidelity designs, you can download the Sketch file from below. It includes a simple styleguide with typography, colors and symbols defined.&lt;/p&gt;
&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Test for Feedback&lt;/h2&gt;
&lt;p&gt;Now that we&apos;re done designing our portfolio, we need to test to see if our design is actually usable by others.&lt;/p&gt;
&lt;p&gt;I&apos;d like to say that you could skip this section if you want. That&apos;s why I&apos;ve called it optional. But then, I strongly urge you to do a bare minimum usability testing at the least.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;
Use &lt;strong&gt;&lt;a href=&quot;https://www.nngroup.com/articles/ten-usability-heuristics/&quot;&gt;Nielsen&apos;s 10 Heuristic principles&lt;/a&gt;&lt;/strong&gt; to troubleshoot your UX portfolio design. Fix anything you can find.&lt;/p&gt;
&lt;p&gt;I agree that robust user testing at this phase can be overkill. So from here, you could do two things, each with its own pros and cons.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Method&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Perform User Testing Now&lt;/p&gt;
&lt;p&gt;Easier to do now with a prototype&lt;br /&gt;
Can uncover usability issues early on&lt;/p&gt;
&lt;p&gt;Can take time away from launching your portfolio&lt;/p&gt;
&lt;p&gt;Get Feedback after launch&lt;/p&gt;
&lt;p&gt;Issues uncovered can be more accurate&lt;/p&gt;
&lt;p&gt;Implementing design changes in development can be hard/time consuming&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;
Here&apos;s how you can &lt;a href=&quot;https://mattish.com/blog/post/how-to-do-a-complete-mobile-guerrilla-user-test-in-under-half-a-day&quot;&gt;conduct quick guerrilla user tests on your own&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you&apos;re designing in Sketch, Adobe XD or Figma, either software lets you quickly transform your design into a prototype.&lt;/p&gt;
&lt;p&gt;You can then share the prototype link which your users can access via any browser to test. Use this via link to test with people. Useful to gauge initial reactions from people. Even better if you&apos;ve designed how your case studies will appear in your portfolio.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;READ&lt;/strong&gt;&lt;br /&gt;
&lt;a href=&quot;https://medium.com/@boagworld/the-best-ux-design-tools-you-need-for-testing-d81614fd5cbb&quot;&gt;Best UX Design Tools for Testing - Paul Boag&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you have the opportunity, test them with hiring managers and other designers you know. Gauge their reactions when they use your website (portfolio). Their feedback is rich information that you can use to further improve your portfolio.&lt;/p&gt;
&lt;p&gt;If you have the luxury to do this, then I highly encourage you to do so. The portfolio designs of mine that I shared with you is the 5th iteration based on user feedback. Many of my design decisions are based off this.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Get Ready for Development Handoff&lt;/h2&gt;
&lt;p&gt;That was one long article but we&apos;re finally at the last step!&lt;/p&gt;
&lt;p&gt;Once your portfolio design is complete (based on how many iterations it took you), the last and final step is handoff.&lt;/p&gt;
&lt;p&gt;Remember what I said about perfection? There is no such thing! So don&apos;t spend time trying to get that &apos;perfect&apos; design. You&apos;ll constantly keep getting new ideas so put it hard stop to it after a point.&lt;/p&gt;
&lt;p&gt;What I&apos;m trying to say is, the last step is preparing for development. So your design needs to be ready to go for this with no further design changes.&lt;/p&gt;
&lt;p&gt;Since this is typically an individual project, you&apos;ll basically be handing it off to yourself (who is also the developer in this case).&lt;/p&gt;
&lt;h3&gt;Use Zeplin for your Design spec&lt;/h3&gt;
&lt;p&gt;Use a tool like &lt;strong&gt;&lt;a href=&quot;https://zeplin.io&quot;&gt;Zeplin&lt;/a&gt;&lt;/strong&gt; to import your portfolio designs. This is a much better way to reference your design specs rather than constantly looking at your Sketch file.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-design/landingPoster.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://zeplin.io&quot;&gt;Zeplin.io&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Zeplin is free upto one project. So go ahead and export your Sketch artboards to Zeplin. Sketch has a handy plugin that can do this for you.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;READ&lt;/strong&gt;&lt;br /&gt;
Learn from Zeplin on &lt;a href=&quot;https://support.zeplin.io/en/articles/1067477-exporting-designs-from-sketch&quot;&gt;how to export from Sketch&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thankfully, Zeplin isn&apos;t that complicated to use. By simply hovering over your designs, Zeplin gives you the specs on the right panel along with code!&lt;/p&gt;
&lt;p&gt;With that, you&apos;re now ready to jump into development!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Recap&lt;/h2&gt;
&lt;p&gt;If you&apos;ve made it this far, then please give yourself a pat on the back. That was definitely not easy for an article this long! Great job!&lt;/p&gt;
&lt;p&gt;Let&apos;s quickly summarize what we did in this design phase.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;First, we looked into what could be the design process for our UX portfolio.&lt;/li&gt;
&lt;li&gt;We started brainstorming ideas for our portfolio by looking at some great portfolio examples from the industry.&lt;/li&gt;
&lt;li&gt;Then, we identified patterns and sketched early ideas on what our portfolio might look like.&lt;/li&gt;
&lt;li&gt;Next, we took our rough sketches and notes to build wireframes, focusing on layout and structure.&lt;/li&gt;
&lt;li&gt;We then evolved our wireframes to medium-fidelity, fleshing out the website content and navigation.&lt;/li&gt;
&lt;li&gt;Finally, we transformed our medium-fidelity to high-fidelity mockups by focusing on visual design&lt;/li&gt;
&lt;li&gt;After completing our design, we looked into how might improve our portfolio design via heuristics or quick guerrilla usability testing.&lt;/li&gt;
&lt;li&gt;Lastly, with our designs now complete, we exported them to Zeplin for development handoff.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Takeaways&lt;/h3&gt;
&lt;p&gt;Design is never finished. While that is true, this is our portfolio and there can be a tendency to endlessly iterate, trying to find that perfect design. It is important to be realistic and acknowledge that fact.&lt;/p&gt;
&lt;p&gt;With that said, here are some last few pointers to keep in mind when you&apos;re in the design phase of your portfolio.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Design keeping your users in mind?&lt;/li&gt;
&lt;li&gt;What do you want your users to takeaway from your portfolio?&lt;/li&gt;
&lt;li&gt;Keep consistency with you as a brand and beliefs as a designer&lt;/li&gt;
&lt;li&gt;Case studies are important – prioritize content over presentation&lt;/li&gt;
&lt;li&gt;When possible - test and get feedback from your target audience&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Next Steps&lt;/h4&gt;
&lt;p&gt;With all that said, we&apos;re now done with the design phase of building your UX portfolio. Cheers!&lt;/p&gt;
&lt;p&gt;We&apos;ve successfully exported our designs to Zeplin, ready to begin development. However, web development has an ocean of choices which can be overwhelming. But not to worry because that&apos;s exactly what I&apos;ll be covering in the next part.&lt;/p&gt;
&lt;p&gt;In Part 3 of Build your UX Portfolio, I&apos;ll talk to you about the frameworks, languages and tools we&apos;ll be using (with choices) to develop your portfolio.&lt;/p&gt;
&lt;p&gt;Be sure to subscribe below so you&apos;ll know when Part 3 is out!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Part 3: Choosing Web Technologies (Coming Soon...)&lt;/em&gt;&lt;/p&gt;
</content:encoded></item><item><title>Build your UX Portfolio From Scratch – Getting Started</title><link>https://blog.iamsuleiman.com/build-ux-portfolio-getting-started/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/build-ux-portfolio-getting-started/</guid><description>Our UX portfolio is a key piece of displaying our capabilities as a designer. Hence, it becomes essential to make one that can speak for you. In this </description><pubDate>Mon, 01 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Our UX portfolio is a key piece of displaying our capabilities as a designer. Hence, it becomes essential to make one that can speak for you.&lt;/p&gt;
&lt;p&gt;In this tutorial series, I will walk you through how I designed and developed my UX portfolio website. Sure, I could&apos;ve named this article as &apos;How I Built My Portfolio&apos; but I want to show you how YOU can do it too. It&apos;s easy, and you don&apos;t need to be a developer. Let me show you.&lt;/p&gt;
&lt;p&gt;Fabricio Teixeira from the UX Collective clearly outlines &lt;a href=&quot;https://uxdesign.cc/what-is-the-real-role-of-a-design-portfolio-website-ee0b5b76112b&quot;&gt;the importance of a portfolio website&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There are those people who can design and also do development. Such hybrid individuals are known in the industry as &lt;strong&gt;UX Engineers&lt;/strong&gt;. In fact, this entire blog is for such individuals!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;UX Engineers weave together strong design aesthetics with technical know-how.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://design.google/jobs/ux-engineer/&quot;&gt;UX Engineer Role @Google&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When you can leverage your talents from both domains. Why not use them to develop your own UX portfolio from scratch?&lt;/p&gt;
&lt;p&gt;It is a powerful way to harness what you know to build a portfolio that&apos;s unique to you. The best part is that you and only you are in control of the whole thing.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-getting-started/building_website.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;**What to expect in this article?&lt;br /&gt;
**This will be an exhaustive, multi-part tutorial series. I will walk you through exactly how I designed and developed my portfolio from scratch. This includes my design process, development tools and how I launched the website. I did all this in one month and I&apos;m no web development expert!&lt;/p&gt;
&lt;p&gt;If you cannot code, don&apos;t worry. I am no web development expert and I got by. I&apos;m here to walk you through it.&lt;/p&gt;
&lt;p&gt;I will show you how to do all this and more. I will also be sharing tons of other resources so be sure to keep an eye out and save them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;There are 3 broad phases of building your UX Portfolio.&lt;/strong&gt;&lt;br /&gt;
Over this multi-part tutorial, I&apos;ll take you through all these phases.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-getting-started/ux_portfolio_broad_process.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I&apos;m a designer. Why do I have to code?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It offers many advantages for you and your UX portfolio (website).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Complete Control&lt;/strong&gt;&lt;br /&gt;
Create a highly customized portfolio and make it unique to you&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Not another clone&lt;/strong&gt;&lt;br /&gt;
Templates are repetitive, which look like other portfolios on the internet&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You own it&lt;/strong&gt;&lt;br /&gt;
You and only you are in complete control of EVERY aspect of the website. Everything belongs to and is owned by you. Using third-party providers leaves you at their mercy since your entire portfolio is with them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Freedom&lt;/strong&gt;&lt;br /&gt;
Third-party portfolio builders can be restrictive, limiting appearance and functionality&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Web development is not hard anymore&lt;/strong&gt;&lt;br /&gt;
Various frameworks help ease and speed up the process&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You learn!&lt;/strong&gt;&lt;br /&gt;
A designer who knows how to code can create feasible solutions that respect technical challenges.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;This is YOUR portfolio - make it your own!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://jessicaivins.net/as-you-learn-ux-design-learn-how-to-code/&quot;&gt;Jessica Ivins beautifully explains&lt;/a&gt; with a real-life story about the &lt;strong&gt;advantages&lt;/strong&gt; you have as a UX Designer who can code.&lt;/p&gt;
&lt;p&gt;The intent of this tutorial series is to help you learn how to custom code your own portfolio from scratch. By the end, you will be able to rapidly develop, modify and maintain your portfolio with ease in the future.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Completely new to Web Development?&lt;/strong&gt;&lt;br /&gt;
If you&apos;re completely new to web development and don&apos;t know HTML or CSS, &lt;strong&gt;&lt;a href=&quot;https://www.w3schools.com/html/default.asp&quot;&gt;W3schools&lt;/a&gt;&lt;/strong&gt; is a great place to start by yourself.&lt;/p&gt;
&lt;p&gt;Alternatively, Udemy has a great course for beginners.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-getting-started/udemy_learn_web_development_basics_w.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Build your UX Portfolio Series&lt;/strong&gt;&lt;br /&gt;
This tutorial is broken up into several parts:&lt;/p&gt;
&lt;p&gt;**Part 1: Getting Started&lt;br /&gt;
**&lt;a href=&quot;https://blog.iamsuleiman.com/build-ux-portfolio-design/&quot;&gt;Part 2: Design&lt;/a&gt;&lt;br /&gt;
Part 3: Choosing A Web Stack &lt;em&gt;(Coming Soon)&lt;/em&gt;&lt;br /&gt;
Part 4: Setting Up Your System To Start Development &lt;em&gt;(Coming Soon)&lt;/em&gt;&lt;br /&gt;
Part 5: Understanding Your Project Environment &lt;em&gt;(Coming Soon)&lt;/em&gt;&lt;br /&gt;
Part 6: Getting Dirty With Code &lt;em&gt;(Coming Soon)&lt;/em&gt;&lt;br /&gt;
Part 7: Optimizing Your Portfolio For Speed &lt;em&gt;(Coming Soon)&lt;/em&gt;&lt;br /&gt;
Part 8: Launch your Website &lt;em&gt;(Coming Soon)&lt;/em&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-getting-started/lets_do_this_meme_quickmeme.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;In part one of this article, I will give you an overview of everything that you need. It should help you prepare and know what to expect from the upcoming articles.&lt;/p&gt;
&lt;p&gt;For experts who have their own UX portfolio wanting to redesign or developers, feel free to skip sections you already know. This article will cover certain sections exhaustively to help those who haven&apos;t done this before.&lt;/p&gt;
&lt;p&gt;I will walk you through the entire process of how I made my portfolio from scratch. My hope is that you can learn from this, avoiding the pitfalls I made thereby saving you tons of time.&lt;/p&gt;
&lt;p&gt;This is how my UX portfolio looks like.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-getting-started/suleiman_portfolio_new.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;My portfolio – &lt;a href=&quot;https://iamsuleiman.com&quot;&gt;iamsuleiman.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My hope is that by the end of these tutorial series, you can create a portfolio like this or better.&lt;/p&gt;
&lt;p&gt;Although it&apos;s not a complete visual overhaul, you&apos;ll be surprised to see the reworked internals. Now, I can easily redesign and add more content and functionality to my UX portfolio in the future. I want to help you do the same.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Quick Navigation&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#getting-started&quot;&gt;Getting Started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#tools-needed&quot;&gt;Tools Needed&lt;/a&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#design-tools&quot;&gt;Design Tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#development&quot;&gt;Development&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#domain-name-hosting-launch&quot;&gt;Domain Name, Hosting &amp;amp; Launch&lt;/a&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#domain-name&quot;&gt;Domain Name&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#hosting&quot;&gt;Hosting&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#wrap-up&quot;&gt;Wrap Up&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#next-steps&quot;&gt;Next Steps&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Tools Needed to Build your UX Portfolio&lt;/h3&gt;
&lt;p&gt;For this tutorial series, we&apos;re going to be using a LOT of different tools and software. So before we begin, here&apos;s a heads up of what we need. Be sure to get them up and running before you start.&lt;/p&gt;
&lt;h4&gt;Design&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Paper &amp;amp; Pencil&lt;/strong&gt;&lt;br /&gt;
For ideation and early concepts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Design Software&lt;/strong&gt;&lt;br /&gt;
From wireframes to high-fidelity mock-ups of what our UX portfolio will look like.&lt;br /&gt;
&lt;em&gt;Recommended&lt;/em&gt; - &lt;strong&gt;&lt;a href=&quot;https://www.sketchapp.com/&quot;&gt;Sketch&lt;/a&gt;&lt;/strong&gt; (Mac-only)&lt;br /&gt;
&lt;em&gt;An Alternative -&lt;/em&gt; &lt;a href=&quot;https://www.adobe.com/products/xd.html&quot;&gt;Adobe XD&lt;/a&gt; (Win &amp;amp; Mac), &lt;a href=&quot;https://www.figma.com/&quot;&gt;Figma&lt;/a&gt; (Free Web tool)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-getting-started/design_tools.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-getting-started/zeplin_logo-1.png&quot; alt=&quot;Zeplin logo&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://zeplin.io/&quot;&gt;Zeplin&lt;/a&gt;&lt;/strong&gt; (Highly recommended!)&lt;br /&gt;
Nice integration with Sketch &amp;amp; now, Adobe XD. It helps enable easy and quick hand-off from design to development. This can speed up your development greatly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prototyping&lt;/strong&gt; (Optional)&lt;br /&gt;
Most UX portfolios are simple. They have a home and about page along with a few case study pages. Rarely are UX portfolios dense, with complex navigation that warrants a prototype.&lt;/p&gt;
&lt;p&gt;Honestly, you can skip this step. But if you feel you need to see the bigger picture, use &lt;strong&gt;&lt;a href=&quot;https://www.invisionapp.com/&quot;&gt;InVision&lt;/a&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;a href=&quot;https://marvelapp.com/&quot;&gt;Marvel&lt;/a&gt;&lt;/strong&gt; for prototyping. Again, I suggest skipping it. I did.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-getting-started/Invision_logo.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-getting-started/marvel_app_logo.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
I understand I&apos;m deviating from a typical design process. But each phase is to serve a purpose. A simple, few-page UX portfolio is not so confusing that it warrants a prototype.&lt;/p&gt;
&lt;p&gt;I talk more in-depth about design in &lt;a href=&quot;https://blog.iamsuleiman.com/build-ux-portfolio-design/&quot;&gt;Part 2&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Development&lt;/h4&gt;
&lt;p&gt;On a minimum level, you need a text editor and &lt;a href=&quot;https://nodejs.org/en/download/&quot;&gt;Node&lt;/a&gt; installed. But don&apos;t worry as I won&apos;t over complicate things at this stage and dump everything in this article.&lt;/p&gt;
&lt;p&gt;The goal for this phase is not to demonstrate our developer prowess as designers (although you could if you want to). But rather, it is to build a UX portfolio quick and easy.&lt;/p&gt;
&lt;p&gt;This is why we&apos;ll be using &lt;a href=&quot;https://getbootstrap.com&quot;&gt;Bootstrap 4&lt;/a&gt; to rapidly build our site and customize it to suit our needs. Then, we will take this a step ahead and automate some repeated web development tasks to speed up our workflow.&lt;/p&gt;
&lt;p&gt;All this and more will be covered in Part 4.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Text Editors&lt;/strong&gt;&lt;br /&gt;
Two really good text editors are &lt;a href=&quot;https://www.sublimetext.com/&quot;&gt;Sublime Text 3&lt;/a&gt; and &lt;a href=&quot;https://atom.io/&quot;&gt;Atom&lt;/a&gt;. I have extensively used both. It ultimately comes down to personal preference.&lt;/p&gt;
&lt;p&gt;Sublime Text or Atom? Trouble deciding? This &lt;a href=&quot;https://www.reddit.com/r/webdev/comments/5v6irh/sublimetext_or_atom_and_why/&quot;&gt;Reddit debate&lt;/a&gt; can help you decide.&lt;/p&gt;
&lt;p&gt;In the end, whatever you choose, familiarize yourself with some handy shortcuts. You&apos;ll be faster and more efficient!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-getting-started/sublime_text_3_logo.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sublime Text 3&lt;/strong&gt;&lt;br /&gt;
&lt;a href=&quot;https://webdesign.tutsplus.com/tutorials/useful-shortcuts-for-a-faster-workflow-in-sublime-text-3--cms-22185&quot;&gt;Useful Shortcuts&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-getting-started/atom_editor_logo.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Atom&lt;/strong&gt;&lt;br /&gt;
&lt;a href=&quot;https://www.sitepoint.com/12-favorite-atom-tips-and-shortcuts-to-improve-your-workflow/&quot;&gt;12 Tips &amp;amp; Shortcuts&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;More on the tech stack in Part 4.&lt;/p&gt;
&lt;h4&gt;Domain Name, Hosting &amp;amp; Launch&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-getting-started/undraw_domain_names_rdql.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Once we&apos;re done developing our UX portfolio, we need to launch it online. For that, we need a domain name and a hosting plan. If you haven&apos;t done this before, don&apos;t worry because it&apos;s much easier than you think. I&apos;ll walk you through this too, outlining some of the best and cost-effective options.&lt;/p&gt;
&lt;p&gt;When your UX portfolio is ready, you need two things to launch.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Domain Name&lt;/li&gt;
&lt;li&gt;Hosting&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Start giving this a thought right from the start!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
Your portfolio could take a while to build. The last thing you want is to see the domain name you wanted is unavailable. Hence, if you have a good domain name in mind, go ahead and buy it first.&lt;/p&gt;
&lt;p&gt;You don&apos;t need powerful hosting options for a UX portfolio website. Get something basic.&lt;/p&gt;
&lt;p&gt;Now, a domain name and hosting are two very different things and each warrants a section of its own. But if you feel this might be too much of a hassle, &lt;strong&gt;just go with a hosting provider that also handles the domain name for you&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;#hosting&quot;&gt;Hosting section of this article&lt;/a&gt; covers this. Otherwise, if you want to get tied in fully by one provider, continue to read on.&lt;/p&gt;
&lt;h5&gt;Domain Name&lt;/h5&gt;
&lt;p&gt;But, I do urge for one thing. &lt;strong&gt;Get yourself a domain name. Now!&lt;/strong&gt; Especially, if you don&apos;t have a portfolio of your own already. If you wait, you might not get the domain name you want. I got mine much before I even had a portfolio - &lt;a href=&quot;https://iamsuleiman.com/&quot;&gt;iamsuleiman.com.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where to buy domain names from?&lt;/strong&gt;&lt;br /&gt;
Here are a few popular names from whom you can buy a domain name. Usually, everyone offers an introductory price for the 1st year. Don&apos;t just go by that though. You want to look at what you&apos;ll be paying every year after the first one.&lt;/p&gt;
&lt;p&gt;Here are a few popular providers. This should give you a sense of how much hosting can cost. Usually, companies offer a highly discounted introductory price. So keep in mind the actual yearly costs after that.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Source&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;(1st year)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Renewal&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.namecheap.com/&quot;&gt;NameCheap&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;$8.88&lt;/p&gt;
&lt;p&gt;$10.98/yr&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.godaddy.com/&quot;&gt;GoDaddy&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;$11.99&lt;/p&gt;
&lt;p&gt;$17.99/yr&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.bluehost.com/&quot;&gt;BlueHost&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;$11.99&lt;/p&gt;
&lt;p&gt;$11.99/yr&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.hostgator.com/&quot;&gt;HostGator&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;$12.95&lt;/p&gt;
&lt;p&gt;$15/yr&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.ionos.com/&quot;&gt;1&amp;amp;1 IONOS&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;$1&lt;/p&gt;
&lt;p&gt;$15/yr&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
None of these are affiliate links. If you buy from any of these providers, I don&apos;t make money from it. So you can be assured that my opinions aren&apos;t biased.&lt;/p&gt;
&lt;p&gt;Personally, I bought my domain from &lt;em&gt;1&amp;amp;1 IONOS.&lt;/em&gt; I find their service very good and reliable. It is a great option if you don&apos;t want to pay too much upfront. Otherwise, &lt;em&gt;NameCheap&lt;/em&gt; is a great alternative that saves you money in the long run.&lt;/p&gt;
&lt;p&gt;Don&apos;t just go by the price. You might want to look into various other factors such as customer support, ease of use and more.&lt;/p&gt;
&lt;p&gt;If you have trouble deciding, here are &lt;a href=&quot;https://bloggingthing.com/best-domain-name-registrars&quot;&gt;the 15 best domain name registrars in 2019&lt;/a&gt;. Many of these services provide hosting too. It should help you decide and pick one.&lt;/p&gt;
&lt;p&gt;**But wait!&lt;br /&gt;
**Before buying a domain, read about hosting too. Certain hosting providers offer a free domain name (for the 1st year) when you buy from them.&lt;/p&gt;
&lt;h5&gt;Hosting&lt;/h5&gt;
&lt;p&gt;So what about hosting then? Consider hosting plans where they offer a free domain for the first year. Having your domain and hosting in one place simplifies a lot of the hosting process.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;
Consider a provider who offers both domain registration and hosting. This can save you the hassle of connecting both and money upfront.&lt;/p&gt;
&lt;p&gt;Here&apos;s a little overview of the cheapest &lt;a href=&quot;https://www.wpbeginner.com/glossary/shared-hosting/&quot;&gt;&lt;em&gt;shared hosting&lt;/em&gt;&lt;/a&gt; plans by hosting providers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Provider&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Price (1yr)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Free Domain&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Storage&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SSL&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Websites&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.inmotionhosting.com/business-hosting&quot;&gt;InMotion&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;$7.46/mo&lt;/p&gt;
&lt;p&gt;Yes&lt;/p&gt;
&lt;p&gt;SSD&lt;/p&gt;
&lt;p&gt;FREE&lt;/p&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.bluehost.com/hosting/shared&quot;&gt;BlueHost&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;$4.95/mo&lt;/p&gt;
&lt;p&gt;Yes&lt;/p&gt;
&lt;p&gt;SSD&lt;/p&gt;
&lt;p&gt;FREE&lt;/p&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.hostgator.com/web-hosting&quot;&gt;HostGator&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;$5.95/mo&lt;/p&gt;
&lt;p&gt;Yes&lt;/p&gt;
&lt;p&gt;Regular&lt;/p&gt;
&lt;p&gt;FREE&lt;/p&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.ipage.com/renewal-pricing&quot;&gt;iPage&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;$7.99/mo&lt;/p&gt;
&lt;p&gt;Yes&lt;/p&gt;
&lt;p&gt;Regular&lt;/p&gt;
&lt;p&gt;Unlimited&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;
Consider buying hosting for at least a year. The longer period you buy for, the lower is your $/month.&lt;/p&gt;
&lt;p&gt;To help you decide, here are &lt;a href=&quot;https://solvid.co.uk/hosting-with-free-domains/&quot;&gt;7 hosting providers who offer a free domain&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you’re a bit nerdy, you might want to see performance tests of some hosts. &lt;strong&gt;&lt;a href=&quot;https://hostingfacts.com/&quot;&gt;Hostingfacts.com&lt;/a&gt;&lt;/strong&gt; &lt;a href=&quot;https://hostingfacts.com/&quot;&gt;has those results&lt;/a&gt; for 30 different providers.&lt;/p&gt;
&lt;p&gt;Personally, I purchased hosting with &lt;a href=&quot;https://www.inmotionhosting.com/&quot;&gt;InMotion Hosting&lt;/a&gt;. Their Business Plans may seem slightly pricier than other competitors. But the SSD storage and free SSL certificate were important for me.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
When a provider says unlimited. It doesn&apos;t actually mean unlimited. There will be a cap limit buried in the details so keep an eye out for that.&lt;/p&gt;
&lt;p&gt;I tried to be brief as I can and yet, give you enough insight. Spend some time picking the right domain registrar and hosting provider for yourself.&lt;/p&gt;
&lt;p&gt;Still, have trouble deciding? Check out the &lt;a href=&quot;https://hostingpill.com/best-web-hosting/&quot;&gt;best web hosting companies for 2019 by HostingPill&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Part 8 will cover how to set everything up and launch your UX portfolio.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Wrap Up&lt;/h3&gt;
&lt;p&gt;I know this might&apos;ve been a lot to digest. But I hope I&apos;ve done my best to convey them to you simply.&lt;/p&gt;
&lt;p&gt;By this point, if not hosting, get a domain name at least (if you haven&apos;t already).&lt;/p&gt;
&lt;p&gt;If all the above was too much to take in for you, then no problem. I made an infographic that has condensed everything I just said above.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Download the free infographic on how to build your UX portfolio.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./build-ux-portfolio-getting-started/ux_portfolio_getting_started_infographic.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/assets/images/build-ux-portfolio-getting-started/ux_portfolio_getting_started_infographic.png&quot;&gt;Download the FREE Infographic&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Next Steps&lt;/h4&gt;
&lt;p&gt;In this article, I hope I have given you a fair overview of the 3 major phases of building our portfolio.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Design&lt;/li&gt;
&lt;li&gt;Development&lt;/li&gt;
&lt;li&gt;Hosting &amp;amp; Launch&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you know someone who wants to build a unique UX portfolio of their own, share this with them! If you have any questions or thoughts, I encourage you to comment below.&lt;/p&gt;
&lt;p&gt;Don&apos;t forget to subscribe if you want to know when the next part comes out!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Read Part 2:&lt;/strong&gt; &lt;a href=&quot;https://blog.iamsuleiman.com/build-ux-portfolio-design/&quot;&gt;Designing your UX Portfolio&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Android Pagination Tutorial – Adding Swipe-to-Refresh</title><link>https://blog.iamsuleiman.com/android-pagination-tutorial-swipe-to-refresh/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/android-pagination-tutorial-swipe-to-refresh/</guid><description>Swipe-to-Refresh is a popular way of refreshing data. In part 5 of the Android pagination tutorial, I will show you how to implement Swipe-to-Refresh.</description><pubDate>Mon, 22 Apr 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Pagination allows loading a long list of data in chunks. You see this in action in news feeds in social media apps, otherwise known as endless or infinite scrolling. In this tutorial, I will specifically show you how to handle pagination with Swipe-to-Refresh involved.&lt;/p&gt;
&lt;p&gt;It took quite a while but finally, welcome to Part 5 of the Android Pagination Tutorial Series!&lt;/p&gt;
&lt;p&gt;Previously in &lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-tutorial-recyclerview-multiple-view-types/&quot;&gt;part 4&lt;/a&gt;, we looked at how to handle pagination when many View Types are involved.&lt;/p&gt;
&lt;p&gt;Swipe-to-Refresh (as Android prefers to call it) or Pull To Refresh (as it is originally called) is a popular way of refreshing your data. But, when you have pagination in play, things can get a little tricky. In this tutorial, I will show you how to handle all those scenarios and implement swipe-to-refresh with pagination.&lt;/p&gt;
&lt;p&gt;This article has been updated for AndroidX!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Android Pagination Series Overview –&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-tutorial-getting-started-recyclerview/&quot;&gt;Getting Started with RecyclerView&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-recyclerview-tutorial-api-retrofit-gson/&quot;&gt;Pagination with APIs using Retrofit and Gson&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-error-handling/&quot;&gt;Error Handling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-tutorial-recyclerview-multiple-view-types/&quot;&gt;Using Multiple RecyclerView Types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Adding Swipe-to-Refresh Support&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
This is a continuation of the Pagination series. Hence this article (code included) assumes that you’ve read and implemented what was discussed in the previous parts.&lt;/p&gt;
&lt;p&gt;If you’re new, I suggest starting with &lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-tutorial-getting-started-recyclerview/&quot;&gt;Part 1 — Implementing the Pagination logic&lt;/a&gt;. Otherwise, if you think you’re good, read on!&lt;/p&gt;
&lt;h2&gt;What is Swipe-to-Refresh?&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;The pull-to-refresh (or swipe-to-refresh) pattern lets a user pull down on a list of data using touch to retrieve more data.&lt;/p&gt;
&lt;p&gt;– &lt;a href=&quot;https://uxplanet.org/pull-to-refresh-ui-pattern-42a85f671cdf&quot;&gt;Pull to Refresh pattern as defined by Nick Babich&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Swipe to Refresh animation. Source: &lt;a href=&quot;https://material.io/design/platform-guidance/android-swipe-to-refresh.html#&quot;&gt;Material Design guidelines&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This pattern was first introduced by &lt;a href=&quot;https://en.wikipedia.org/wiki/Loren_Brichter&quot;&gt;Loren Brichter&lt;/a&gt; in the Tweetie app (which was &lt;a href=&quot;https://techcrunch.com/2010/04/09/twitter-acquires-tweetie/&quot;&gt;acquired by Twitter back in 2010&lt;/a&gt;). In fact, the design pattern became so popular that &lt;a href=&quot;https://www.theverge.com/2013/5/21/4350826/twitter-pull-to-refresh-patent-innovators-patent-agreement-announced&quot;&gt;Twitter even holds a patent on it&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When to use it?&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Swipe to Refresh is best to use this gesture with dynamic content that has frequent updates…&lt;/p&gt;
&lt;p&gt;– Swipe to Refresh as defined in Material Design&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Material Design has very &lt;a href=&quot;https://material.io/design/platform-guidance/android-swipe-to-refresh.html&quot;&gt;detailed guidelines on Swipe to refresh&lt;/a&gt;, how to design for it and when to use it. I recommend everyone to read it.&lt;/p&gt;
&lt;p&gt;Now what we know what Swipe to Refresh is and when to use it. Let’s get to actually implementing it.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Implementing Swipe-to-Refresh&lt;/h3&gt;
&lt;p&gt;To implement Swipe to Refresh, we need to do 3 things.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Add the &lt;code&gt;SwipeRefreshLayout&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add support via a refresh menu action&lt;/li&gt;
&lt;li&gt;Creating the refresh callback action&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Once we’ve done these 3, we need to tie in our pagination callbacks with the Swipe to Refresh action. Let’s begin with the first step.&lt;/p&gt;
&lt;h4&gt;Add the &lt;code&gt;SwipeRefreshLayout&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Go to the &lt;code&gt;MainActivity&lt;/code&gt; layout file, &lt;code&gt;activity_main.xml&lt;/code&gt; and add the &lt;code&gt;**SwipeRefreshLayout**&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You’ll have a &lt;code&gt;RecyclerView&lt;/code&gt; layout that we’re using to handle the pagination. This &lt;code&gt;RecyclerView&lt;/code&gt; now needs to be wrapped with a &lt;a href=&quot;https://developer.android.com/reference/android/support/v4/widget/SwipeRefreshLayout.html&quot;&gt;&lt;code&gt;SwipeRefreshLayout&lt;/code&gt;&lt;/a&gt;. Look at the XML layout’s skeleton below for the code.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;FrameLayout&amp;gt;	
    &amp;lt;android.support.v4.widget.SwipeRefreshLayout
        android:id=&quot;@+id/main_swiperefresh&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;match_parent&quot;&amp;gt;

        &amp;lt;androidx.recyclerview.widget.RecyclerView /&amp;gt;

    &amp;lt;/android.support.v4.widget.SwipeRefreshLayout&amp;gt;

    &amp;lt;ProgressBar /&amp;gt;
&amp;lt;/FrameLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Add the Refresh Menu Item&lt;/h4&gt;
&lt;p&gt;From a design perspective, if you think about your app&apos;s users, a refresh action is needed on your &lt;code&gt;Toolbar&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You should add a refresh action to your app&apos;s action bar to ensure that users who may not be able to perform a swipe gesture can still trigger a manual update.&lt;/p&gt;
&lt;p&gt;– &lt;a href=&quot;https://developer.android.com/training/swipe/add-swipe-interface&quot;&gt;Android Developer Guidelines&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Start by adding the refresh icon to your &lt;code&gt;Activity&lt;/code&gt;&apos;s &lt;em&gt;menu.xml&lt;/em&gt; file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;menu&amp;gt;
    &amp;lt;item
        android:id=&quot;@+id/menu_refresh&quot;
        android:title=&quot;@string/menu_refresh&quot;
        app:showAsAction=&quot;never&quot;/&amp;gt;
&amp;lt;/menu&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, override the &lt;code&gt;onOptionsItemSelected()&lt;/code&gt; method in your &lt;code&gt;Activity&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override
public boolean onOptionsItemSelected(MenuItem item) {
 switch (item.getItemId()) {
  case R.id.menu_refresh:
   // Signal SwipeRefreshLayout to start the progress indicator
   swipeRefreshLayout.setRefreshing(true);
   doRefresh();
 }
 return super.onOptionsItemSelected(item);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that when the Swipe-to-Refresh action is triggered, you need to show that it&apos;s refreshing. That&apos;s what the loading indicator shows.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-pagination-tutorial-swipe-to-refresh/patterns_swipetorefresh_dont2_b3h7nn.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Swipe-to-Refresh. Image Credits - &lt;a href=&quot;http://sapandiwakar.in/pull-to-refresh-for-android-recyclerview-or-any-other-vertically-scrolling-view/&quot;&gt;sapandiwakar.in&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;But also be sure to dismiss it when the refreshing is complete. You can do this by &lt;code&gt;**swipeRefreshLayout.setRefreshing(false)**&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Note the &lt;code&gt;doRefresh()&lt;/code&gt; method. This will handle our actual refresh logic which I will cover in the next step.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;
A good app is one that thinks about its diverse user base. Adding an explicit refresh action helps with accessibility, allowing people to see an action that they otherwise wouldn&apos;t.&lt;/p&gt;
&lt;p&gt;So that&apos;s one for good UX design! Now that we have the UI controls in place, the last thing we need to do is create the Swipe-to-Refresh callback.&lt;/p&gt;
&lt;p&gt;Now we&apos;ve created a working Swipe-to-Refresh UI control. But, it doesn&apos;t do anything yet. Next, let&apos;s hook our Pagination to this.&lt;/p&gt;
&lt;h4&gt;Create the Refresh Callback Action&lt;/h4&gt;
&lt;p&gt;Before we get to the &lt;code&gt;doRefresh()&lt;/code&gt; method, we&apos;ve added the action via the Toolbar menu&apos;s refresh. But what about the actual Swipe-to-Refresh?&lt;/p&gt;
&lt;p&gt;In other words, we need to listen when we swipe from the top. The same &lt;code&gt;doRefresh()&lt;/code&gt; action will happen when we trigger Swipe-to-Refresh. We can do this via a simple listener.&lt;/p&gt;
&lt;p&gt;In your &lt;code&gt;Activity&lt;/code&gt;, add this code to its &lt;code&gt;onCreate()&lt;/code&gt; method.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;swipeRefreshLayout.setOnRefreshListener(this::doRefresh);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
The above code is simplified with &lt;a href=&quot;https://developer.android.com/studio/write/java8-support&quot;&gt;Java 8 Lambdas for Android&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;doRefresh()&lt;/code&gt; method will handle the actual logic of refreshing via Swipe-to-Refresh.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private void doRefresh() {
 progressBar.setVisibility(View.VISIBLE);
 if (callTopRatedMoviesApi().isExecuted())
  callTopRatedMoviesApi().cancel();

 adapter.getMovies().clear();
 adapter.notifyDataSetChanged();
 loadFirstPage();
 swipeRefreshLayout.setRefreshing(false);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here&apos;s what the &lt;code&gt;doRefresh()&lt;/code&gt; method does.&lt;/p&gt;
&lt;p&gt;First, remember to show the progress indicator. Clearing the adapter and making a fresh request can make the screen blank.&lt;/p&gt;
&lt;p&gt;Then, check if any API&apos;s are being executed, these are the page load requests. If you recall, it is one single API call to which we pass the page number. This is done via the &lt;code&gt;callTopRatedMoviesApi()&lt;/code&gt; method. Hence, we check if this API called is being executed and if yes, cancel it.&lt;/p&gt;
&lt;p&gt;Next, we clear the list of existing data and notify the adapter of these changes. Then, we make a fresh request to the first page. Lastly, don&apos;t forget to &lt;code&gt;setRefreshing(false)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Remember that the &lt;code&gt;doRefresh()&lt;/code&gt; method will be triggered regardless of whether it is via a swipe or via refresh in the &lt;code&gt;Toolbar&lt;/code&gt;.&lt;/p&gt;
&lt;h5&gt;The Problem with this Approach&lt;/h5&gt;
&lt;p&gt;Swipe-to-Refresh (going by its very definition), allows you to update (refresh) the existing data you have.&lt;/p&gt;
&lt;p&gt;In pagination, the first page is loaded and presented by default. Page 2 and beyond loads as you keep scrolling down to the bottom of the list.&lt;/p&gt;
&lt;p&gt;When you trigger a Swipe-to-Refresh, you request for page 1 again and load its fresh data. All other consecutive page data is removed and Pagination will begin fresh.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When to actually refresh?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;While that&apos;s simple on paper, doing as I mentioned above is wrong. Think about it, constantly calling Swipe-to-Refresh keeps making a request for Page 1. But do we even know if Page 1 has updated or fresh data to display? If it is the same data, why are we making a network call for the same thing?&lt;/p&gt;
&lt;p&gt;So how do we go about this? We use &lt;strong&gt;&lt;a href=&quot;https://medium.com/@appmattus/caching-made-simple-on-android-d6e024e3726b&quot;&gt;caching&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;h5&gt;Use Caching&lt;/h5&gt;
&lt;p&gt;Caching allows us to store the data on memory and has an expiry (time) range associated with it. As long as the data hasn&apos;t expired, making a network call for that data will request the cache rather than the network.&lt;/p&gt;
&lt;p&gt;When it has expired, the cache becomes stale. This time when a request is made, it is made from the network allowing fresh data to be displayed and the cache to be updated.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
As app developers, we need to be judicious with consuming data. We don&apos;t want to be spamming API calls that have no meaning. It wastes data and server resources.&lt;/p&gt;
&lt;p&gt;So what do we need to do? With Swipe-to-Refresh or Pagination, there is no logic change. But, what we do need to do is modify &lt;a href=&quot;https://square.github.io/retrofit/&quot;&gt;Retrofit&lt;/a&gt; to support caching.&lt;/p&gt;
&lt;h3&gt;Modifying Retrofit to Support Caching&lt;/h3&gt;
&lt;p&gt;While this might be out of scope for this tutorial, it is essential to establish good practices. In this scenario, doing a Swipe-to-Refresh with pagination can abuse the network calls. Caching can help prevent this and encourage developers to build a performant app.&lt;/p&gt;
&lt;p&gt;So firstly, we need to modify Retrofit to support caching in its network requests. To do this, open the &lt;em&gt;&lt;strong&gt;MovieApi&lt;/strong&gt;&lt;/em&gt; class. There are 3 things we need to do.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Declare cache&lt;/li&gt;
&lt;li&gt;Define &lt;code&gt;Interceptor&lt;/code&gt; to read cache&lt;/li&gt;
&lt;li&gt;Add both to your Client Builder&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;1. Declare Cache&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;public class MovieApi {
 // 10MB Cache size
 private final static long CACHE_SIZE = 10 * 1024 * 1024;
 ...

 private static OkHttpClient buildClient(Context context) {
  ...
  // Create Cache
  Cache cache = new Cache(context.getCacheDir(), CACHE_SIZE);

  return new OkHttpClient
   .Builder()
   ...
   .cache(cache)
   .build();
 }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2. Define &lt;code&gt;Interceptor&lt;/code&gt; to Read Cache&lt;/h4&gt;
&lt;p&gt;Next, define the &lt;code&gt;Interceptor&lt;/code&gt;. This allows us to intercept the network requests we make and read their &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control&quot;&gt;Cache-Control headers&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class MovieApi {
 ...
 private static OkHttpClient buildClient(Context context) {
   // Build interceptor
   final Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = chain -&amp;gt; {
    Response originalResponse = chain.proceed(chain.request());
    if (NetworkUtil.hasNetwork(context)) {
     int maxAge = 60; // read from cache for 1 minute
     return originalResponse.newBuilder()
      .header(&quot;Cache-Control&quot;, &quot;public, max-age=&quot; + maxAge)
      .build();
    } else {
     int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
     return originalResponse.newBuilder()
      .header(&quot;Cache-Control&quot;, &quot;public, only-if-cached, max-stale=&quot; + maxStale)
      .build();
    }
   };
   ...
  }
  ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, we must add this to our &lt;code&gt;OkHttpClient.Builder&lt;/code&gt;. So it finally will look like this.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;return new OkHttpClient
 .Builder()
 .addNetworkInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)
 .cache(cache)
 .build();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So we first, created our &lt;code&gt;Cache&lt;/code&gt; and added it to the request builder. Next, we created an interceptor to read the Cache-Control headers from every request and added that to the request builder too.&lt;/p&gt;
&lt;h4&gt;Request from Network or Cache?&lt;/h4&gt;
&lt;p&gt;Now that we&apos;ve modified Retrofit to support caching, how do we actually know if a specific request is from cache or not?&lt;/p&gt;
&lt;p&gt;A simple if-else condition check for the &lt;a href=&quot;https://square.github.io/retrofit/2.x/retrofit/retrofit2/Response.html&quot;&gt;&lt;code&gt;Response&lt;/code&gt;&lt;/a&gt; will tell us.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (response.raw().cacheResponse() != null) {
 //    Cache Response
} else {
 //    Network Response
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can read more about this on &lt;a href=&quot;https://stackoverflow.com/questions/41727750/detect-if-okhttp-response-comes-from-cache-with-retrofit&quot;&gt;StackOverflow&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Tying it all with Swipe-to-Refresh&lt;/h4&gt;
&lt;p&gt;With this simple modification, you can use the above if-else to check where your data is coming from. You can log your network requests to check. The very first time you make a request, it&apos;ll be from the network. When a request is made again, it comes from the cache. The latter will continue to happen until the cache goes stale (expires).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Just a stepping point...&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I don&apos;t want to digress too much from the goal of this tutorial, which is to implement Swipe-to-Refresh and support pagination.&lt;/p&gt;
&lt;p&gt;However, we went beyond to use good design principles and implemented caching. Although this implementation works, it is very simple in its working and scope.&lt;/p&gt;
&lt;p&gt;I highly encourage you to go beyond and fully test the caching mechanism.&lt;/p&gt;
&lt;p&gt;For instance, let&apos;s look at the &lt;code&gt;doRefresh()&lt;/code&gt; method again.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private void doRefresh() {
 progressBar.setVisibility(View.VISIBLE);
 if (callTopRatedMoviesApi().isExecuted())
  callTopRatedMoviesApi().cancel();

 adapter.getMovies().clear();
 adapter.notifyDataSetChanged();
 loadFirstPage();
 swipeRefreshLayout.setRefreshing(false);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This method currently refreshes the adapter with fresh data. By fresh I mean fetching from cache again if a network request was already made. In other words, you&apos;re clearing the Adapter and repopulating it with the SAME data. Wouldn&apos;t you agree that&apos;s wasted work?&lt;/p&gt;
&lt;p&gt;A better way to do this is to NOT repopulate the data. Don&apos;t clear the data and load the first page again. Instead, you could make a short API call or check to see if there is any fresh data available in the server, if yes, then perform the actual swipe to refresh. Now you know there&apos;s fresh data available which will make the fetch meaningful.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;
A better approach is to not wait for the cache to expire. Rather check the server if there is fresh data available. If yes, then refresh the adapter with new data. Otherwise, don&apos;t bother doing the reload with Swipe-to-Refresh since it is the same data.&lt;/p&gt;
&lt;p&gt;If you&apos;re interested in reading more about Caching with Retrofit, &lt;a href=&quot;https://medium.com/mindorks/caching-with-retrofit-store-responses-offline-71439ed32fda&quot;&gt;Midorks has a great Medium article&lt;/a&gt; on it.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Output&lt;/h3&gt;
&lt;p&gt;Now that we&apos;ve done all that&apos;s needed to implement Swipe-to-Refresh for pagination, let&apos;s see how it looks like in action.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/android-pagination-tutorial-swipe-to-refresh/pagination_swipe_refresh.gif&quot; alt=&quot;android pagination recyclerview 5 swipe to refresh output&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Project Available on GitHub&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Suleiman19/Android-Pagination-with-RecyclerView/tree/46be39351bc7366061797fb2545686b141c1779c&quot;&gt;Get the Source Code&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;In this tutorial, we looked at adding Swipe-to-Refresh support to Pagination. Again, the hardest part was implementing the Pagination logic, which we&apos;ve done in &lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-tutorial-getting-started-recyclerview/&quot;&gt;Part 1&lt;/a&gt;. Swipe-to-Refresh was a simple add-on to that relatively.&lt;/p&gt;
&lt;p&gt;Next, we also looked at implementing a simple caching mechanism by modifying Retrofit. This allowed us to not abuse network calls with Swipe-to-Refresh.&lt;/p&gt;
&lt;p&gt;Lastly, if you&apos;ve read the tutorial up to this point, this marks the end of the Pagination tutorial series. Congratulations on making through all five parts!&lt;/p&gt;
&lt;p&gt;I hope you found this useful as I&apos;ve enjoyed writing this for you.&lt;/p&gt;
&lt;p&gt;Have I covered everything you need to know about adding Pagination in your apps? Or do you have any questions? Tell me in the comments below and I&apos;ll get back to you.&lt;/p&gt;
&lt;p&gt;Lastly, if you loved reading this article, share it with others so they can learn too!&lt;/p&gt;
</content:encoded></item><item><title>How To Design A Great Mobile App Intro By Learning From The Best</title><link>https://blog.iamsuleiman.com/design-great-mobile-app-intro/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/design-great-mobile-app-intro/</guid><description>The App Intro or Product Tour is an introductory welcome experience for first-time users to your product. In this article, we will look at how to desi</description><pubDate>Mon, 02 Jul 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The App Intro or Product Tour is an introductory welcome experience for first-time users to your product. In this article, we will look at how to design great app intros by learning from the best mobile apps. The App Intro or Product Tour is the first part of your overall onboarding experience and hence, the most important. For the sake of this article, I will stick to calling it the App Intro. At first, I too was calling Intros as Onboarding but for the sake of brevity and not to mislead, I felt it would be best if the correct terms were used. Now the terms &apos;&lt;em&gt;App Onboarding&lt;/em&gt;&apos; and &apos;&lt;em&gt;App Intro&lt;/em&gt;&apos; might be used interchangeably sometimes. So it is best we clarify the difference between the two. In this article, let&apos;s begin by first clarifying the difference between the two terms. Next, we&apos;ll look at the problem that mobile apps typically face and how an app intro can help. Then, we will look at how app intros are designed by 3 popular mobile apps. We will then learn from these examples to design a mobile app intro of our own. Lastly, I will leave you with some brilliant resources to further learn from. So with that said, let’s dive in.&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Onboarding VS App Intro&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Instead of me trying to explain the difference to you in words, I hope the image below does a better job.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./design-great-mobile-app-intro/user_onboarding_not_app_intro.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;READ:&lt;/strong&gt; &lt;a href=&quot;https://blog.iamsuleiman.com/material-design-onboarding-android-quickstart-tap-target/&quot;&gt;Implement Material Design On-boarding in Android&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;What&apos;s evidently clear is that User Onboarding is NOT the same as the App Intro. They are two entirely different things. The App Intro only serves as an introduction or as a welcome to new users, giving them an overview of what the app is. The intro is simply a small part of the entire app&apos;s overall onboarding experience. &lt;strong&gt;User Onboarding&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;User onboarding is the process of increasing the likelihood that new users become successful when adopting your product.&quot; — Samuel Hulick of &lt;a href=&quot;https://www.useronboard.com&quot;&gt;UserOnboard.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Want to learn more about onboarding? Chameleon has a great &lt;a href=&quot;https://www.trychameleon.com/blog/onboarding-flows&quot;&gt;guide to onboarding flows&lt;/a&gt; with useful tips and examples. &lt;strong&gt;App Intro&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The &lt;em&gt;intro screen&lt;/em&gt; is a great way to showcase your app&apos;s greatest features. It is simply, one of the ways by which you can increase retention rates. The App Intro screen is a small part of the overall onboarding experience that you can build for your app.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./design-great-mobile-app-intro/app_intro_collage.png&quot; alt=&quot;&quot; title=&quot;App Intro designs concepts from various apps&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Want more app intro inspiration? You can see &lt;a href=&quot;https://medium.com/inspiration-supply/examples-of-onboarding-design-in-mobile-apps-2243ca298b8b&quot;&gt;40+ example designs for mobile apps here&lt;/a&gt;. For the sake of this article, we’ll focus on just &lt;strong&gt;mobile app intros&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;The problem with mobile apps&lt;/h3&gt;
&lt;p&gt;A good rule of thumb for creating mobile apps is to understand that your users are always on the go and hard-pressed for time. Hence it’s essential that we keep these constraints in mind. The purpose of apps is to be laser-focused on helping users do the one thing they need to do, really well and quickly.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Get users to be able to do what they want via your app, in the fastest way possible.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It is no secret that mobile apps have always struggled with retention. &lt;strong&gt;On average, mobile apps could lose 75% of their users in 3 months&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./design-great-mobile-app-intro/Retention_by_day_numbers.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Nobody cares about the thing you’ve designed unless you can get them past the beginning.&quot; — &lt;a href=&quot;https://medium.com/the-year-of-the-looking-glass/design-the-beginning-b8e61081ce42&quot;&gt;Julie Zhuo&lt;/a&gt;, Product Design VP, Facebook&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;Really Good Mobile App Intro Designs To Learn From&lt;/h2&gt;
&lt;p&gt;Now we know what an app intro is and it&apos;s importance in helping retention rates. Next, we&apos;ll look at 3 really good mobile app intros, do a breakdown of each and see why it works well. We will then learn from these 3 examples and see how to bring it all together for your app. In design, there never is a &apos;one size fits all&apos; solution. So instead of trying to decide upon one approach, let&apos;s take a look at 3 best onboarding experiences on apps. Keep in mind that I am deliberately trying to be device agnostic. &lt;strong&gt;The goal is to look at how app intros have been designed&lt;/strong&gt; so Android or iOS has no effect on this. The 3 apps that we&apos;ll look into are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Evernote&lt;/li&gt;
&lt;li&gt;Spotify&lt;/li&gt;
&lt;li&gt;LinkedIn&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;&lt;strong&gt;1. Evernote&lt;/strong&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;An extremely popular app for note-taking, to-do lists and much more.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./design-great-mobile-app-intro/2cccbbbb63ac74bc5e77c8fb61974b36.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;2. Spotify&lt;/strong&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Spotify&lt;/em&gt; is a digital music service that gives you access to millions of songs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Notice how Spotify breaks down its value proposition into simple, digestible chunks, displayed one at a time in a carousel.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./design-great-mobile-app-intro/spotify-sign-up-1.png&quot; alt=&quot;&quot; title=&quot;Spotify iOS App Intro - [apptimize.com](https://apptimize.com/blog/2017/06/largest-apps-revenue-ace-user-onboarding/)&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;3. LinkedIn&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Linkedin&lt;/em&gt; is a professional networking service that includes recruiters, job seekers and alike.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./design-great-mobile-app-intro/linkedin-students-intro.jpg&quot; alt=&quot;&quot; title=&quot;LinkedIn App Intro - [graetnew.com](https://graetnew.com/new-linkedin-apps-beneficial-for-b2b-strategies/)&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Identifying what works&lt;/h2&gt;
&lt;p&gt;Remember there is no straightforward answer or a &apos;one size fits all&apos; solutions. But I am sure that those who designed those app intros have a pretty solid understanding of that. So what we can do is learn from these designs. By looking at the three app intro designs, we can learn from them and identify common patterns. This will help us establish a foundation to build upon for our own apps. With that said, &lt;strong&gt;let&apos;s go through the common components that make up a good app intro.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./design-great-mobile-app-intro/app-intro-ui-common-elements.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The image above highlights the most common components of app intros. If you looked at all the app intro examples previously mentioned above, you can see the relation. Next, we will focus on each of these components individually and make note of the design choices each have taken and why that may be. This will further help us design our own app intros better.&lt;/p&gt;
&lt;h3&gt;1. Header Copy&lt;/h3&gt;
&lt;p&gt;Most headers include a distinct headline followed by a two-line text description.  LinkedIn however, opted to not visually distinguish their copy keeping it simple. Note that each description uses a thoughtful choice of words that evokes clarity on what the app has to offer users.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./design-great-mobile-app-intro/app-intro-common-component-headline.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Takeaways:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clear heading and subheading (except for LinkedIn)&lt;/li&gt;
&lt;li&gt;Distinct typography between heading and subheading&lt;/li&gt;
&lt;li&gt;Short headlines and clear copy&lt;/li&gt;
&lt;li&gt;Simple words used to indicate value proposition&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. Image&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./design-great-mobile-app-intro/spotify-search-app-intro.png&quot; alt=&quot;&quot; title=&quot;Spotify App intro using meaningful imagery for Search&quot; /&gt;&lt;/p&gt;
&lt;p&gt;We&apos;ve seen app intros using simple, full-blown imagery with great photography to videos. We&apos;ve also seen delightful animations as well. Perhaps now, what we&apos;ve come to increasingly see is custom illustrations like the one you see in Spotify. However, that&apos;s not to say that what&apos;s currently trending is the way to go. Look at the image choices used by Spotify. Notice the meaningful imagery used for &apos;Search&apos;. A long road ahead tells that there&apos;s a lot to be discovered along the way. A beautiful representation for Search. &lt;strong&gt;&lt;a href=&quot;https://unsplash.com&quot;&gt;unsplash.com&lt;/a&gt;&lt;/strong&gt; provides brilliant photography that you can use for free. Be it photographs, UI components with animations or custom illustrations, they are all simply a design choice. You can already see the variety used here in these three apps. So pick one that goes with your brand or app&apos;s character. In other words, opt for a style that obeys your visual language that resonates across your app.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;READ:&lt;/strong&gt; &lt;a href=&quot;https://blog.iamsuleiman.com/techniques-to-display-text-overlay-background-images/&quot;&gt;Techniques to Display Text over Images&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./design-great-mobile-app-intro/app-intro-common-component-illustration.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Personally, I like how Spotify uses clean illustrations to visually depict what it has to offer. From a technical standpoint, &lt;a href=&quot;https://watb.co.uk/5-reasons-you-should-be-using-svgs-over-pngs/&quot;&gt;SVG illustrations are more light-weight than PNG images&lt;/a&gt;. But images can still be powerful to convey meaning or evoke emotion if the right one is used. &lt;strong&gt;Takeaways:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Distinct, simple illustrations that respect brand character (Evernote)&lt;/li&gt;
&lt;li&gt;Using professional photography as a full-blown background image (Spotify)&lt;/li&gt;
&lt;li&gt;Using pieces of the UI to &apos;educate&apos; users on what to expect (LinkedIn)&lt;/li&gt;
&lt;li&gt;Visual indicator for a swipe-able carousel that reveals more features of the app&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. CTA Button&lt;/h3&gt;
&lt;p&gt;The Call-to-Action (CTA) button for almost every app intro is to either create a new account or log in. A CTA present throughout the app intro implies something very important. You want your (first-time) users to know what your app has to offer. But you also don&apos;t want to force them to see through it all. You don&apos;t want your users to sit, swiping through multiple carousels before they can get to the signup screen. Then, the signup is another bunch of screens before they can actually get to use the app.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./design-great-mobile-app-intro/app-intro-common-component-cta.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Don&apos;t force your users to see what you have to offer. If they&apos;re interested in knowing, they will go through it. Maybe they already know about your product. Don&apos;t forcefully re-educate them again. Allow them to skip to log in, signup or directly to the home screen. Remember that mobile users are impatient. We need to remember, respect that and let them get down to using your app, in the fastest way possible. Takeaways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;One simple button to &apos;Get Started&apos;, although it can be ambiguous (Evernote)&lt;/li&gt;
&lt;li&gt;Clear buttons that respect both first-time and returning users to sign up or login respectively (Spotify)&lt;/li&gt;
&lt;li&gt;Clever button design with clear visual distinction for emphasis on &apos;sign up&apos; rather than &apos;sign in&apos; (LinkedIn &amp;amp; Spotify)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Putting it all together - Design your own App Intro&lt;/h3&gt;
&lt;p&gt;Up till now, we&apos;ve identified the three common components that make up a good app intro. Then we looked at how our three app approach and design these components. Next, we will harness all that we&apos;ve learned and design an app intro of our own. Here&apos;s what I&apos;ve designed. I also took some extra liberty to make a &lt;a href=&quot;https://dribbble.com/shots/4777982-App-Intro-Concept-Design&quot;&gt;Dribbble shot&lt;/a&gt; because, why not?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./design-great-mobile-app-intro/app-intro-design-suleiman.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Let me better explain the design choices here and how I copied *cough* drew inspiration from others.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Image:&lt;/strong&gt; Opted for a minimal, clean SVG illustration that respects the brand color palette. In this way, it better fit with the minimal design I was going for, rather than an actual photograph. Also, I got this beautiful SVG illustration for free from &lt;a href=&quot;https://undraw.co&quot;&gt;&lt;strong&gt;unDraw.co&lt;/strong&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Header Copy:&lt;/strong&gt; Used a simple, clear font &lt;a href=&quot;https://fonts.google.com/specimen/Source+Sans+Pro&quot;&gt;Source Sans Pro&lt;/a&gt;. Personally, I&apos;m not a fan of using two different fonts. I rather stick with one and play around with font weights and colors for consistency. But use-cases can vary.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CTA Button:&lt;/strong&gt; Primary action indicated by a bold, vivid button that gets most of the attention. The secondary action could&apos;ve been a button too. But it could fight for attention with the primary action.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;Going beyond a simple &apos;App Intro&apos;&lt;/h2&gt;
&lt;p&gt;In this article, we&apos;ve spoken extensively about how to design an app intro. But it doesn&apos;t just stop here and you should take it to the next level. Remember that the intro is just one part of the entire onboarding experience. Onboarding can be more personal and in-context. Moreover, to learn about great product onboarding, don&apos;t just restrict yourself to mobile apps. Amazing inspirations can be found on websites too. Look to how websites implement their onboarding and you&apos;d be amazed to see what you can take away from there and implement in your own apps. A great starting point is the &lt;a href=&quot;https://www.useronboard.com&quot;&gt;User Onboarding Teardowns by Samuel Hulick&lt;/a&gt;. There are detailed case studies where you can learn a lot from popular apps.&lt;/p&gt;
&lt;h3&gt;Key Takeaways&lt;/h3&gt;
&lt;p&gt;In this article, we saw how to design app intros by seeing how some of the best apps do it. We then identified that there are 3 main components that must be included in your app intro designs - the header copy, an image and a CTA. Lastly, remember that the app intro is only the beginning and a very small part of the overall onboarding journey. Apps need to deliver to their users fast! So get them familiar with your apps in the fastest way possible. Remember that mobile app users will not wait. Educate them early and educate them fast. &lt;strong&gt;More Resources:&lt;/strong&gt; Mobile Onboarding inspiration gallery  - &lt;a href=&quot;https://www.mobile-patterns.com/onboarding&quot;&gt;mobile-patterns.com&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Android Pagination Tutorial—Handling Multiple View Types</title><link>https://blog.iamsuleiman.com/android-pagination-tutorial-recyclerview-multiple-view-types/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/android-pagination-tutorial-recyclerview-multiple-view-types/</guid><description>Pagination is also known as endless or infinite scrolling. This is achieved using RecyclerView. In this tutorial, I’ll show you how to paginate when m</description><pubDate>Tue, 08 Aug 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Pagination is also known as endless or infinite scrolling. This is achieved using &lt;code&gt;RecyclerView&lt;/code&gt;. In this tutorial, I’ll show you how to paginate when multiple View Types are involved.&lt;/p&gt;
&lt;p&gt;Welcome to part 4 of the Android Pagination Tutorial Series!&lt;/p&gt;
&lt;p&gt;Previously in part 3, we identified various scenarios in which errors can occur. Then, we saw how to handle these Pagination errors via code and present them to users.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;RecyclerView&lt;/code&gt; is well known for supporting multiple view types. What if you wanted to do that and paginate the list, at the same time? Let’s look at just that, in this tutorial.&lt;/p&gt;
&lt;p&gt;This article has been updated for AndroidX!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Android Pagination Series Overview&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-tutorial-getting-started-recyclerview/&quot;&gt;Getting Started with RecyclerView&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-recyclerview-tutorial-api-retrofit-gson/&quot;&gt;Pagination with APIs using Retrofit and Gson&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-error-handling/&quot;&gt;Error Handling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Using Multiple RecyclerView Types&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-tutorial-swipe-to-refresh/&quot;&gt;Adding Swipe-to-Refresh Support&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; This is a continuation of the Pagination series. Hence this article (code included) assumes that you’ve read and implemented what was discussed in the previous parts.&lt;/p&gt;
&lt;p&gt;If you’re new, I strongly suggest you start with &lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-tutorial-getting-started-recyclerview/&quot;&gt;Part 1 — Implementing the Pagination logic&lt;/a&gt;. Otherwise, if you think you’re good, read on!&lt;/p&gt;
&lt;h2&gt;Supporting Multiple View Types in RecyclerView&lt;/h2&gt;
&lt;p&gt;Often, when you want to display a list, all the items aren’t the same. Commonly, your first item might be a hero image, followed by a list.&lt;/p&gt;
&lt;p&gt;We all know too well that when multiple &lt;code&gt;View&lt;/code&gt; Types are involved, the code tends to get verbose. Additionally, with Pagination in play, things are about to get ugly.&lt;/p&gt;
&lt;p&gt;However, that doesn’t have to be the case. Code complexity should not scare you. Provided you spend little time organizing your codebase.&lt;/p&gt;
&lt;p&gt;If you remember from the previous tutorials, we already have 2 view types in our &lt;code&gt;RecyclerView&lt;/code&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The regular list item&lt;/li&gt;
&lt;li&gt;Loading footer&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;But the loading footer is only temporary, it briefly appears until the next page loads. After that, it disappears.&lt;/p&gt;
&lt;p&gt;So let’s go ahead and add a third &lt;code&gt;View&lt;/code&gt; type — a Hero image as the first item in the list.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-pagination-tutorial-recyclerview-multiple-view-types/pagination-multiple-view-types-preview.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;What we&apos;ll be creating&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Creating the Hero ViewHolder&lt;/h3&gt;
&lt;p&gt;Adding a new &lt;code&gt;View&lt;/code&gt; Type is a simple thing to do. If you’re familiar with &lt;code&gt;RecyclerView&lt;/code&gt;, you should know this by now as well.&lt;/p&gt;
&lt;p&gt;I strongly encourage you to create your own, without referencing this section. However, if you need help, I’ve got your back!&lt;/p&gt;
&lt;p&gt;There’s no set way to go about it, but here are the steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create XML layout for your new View&lt;/li&gt;
&lt;li&gt;Update Item View Types&lt;/li&gt;
&lt;li&gt;Create it’s ViewHolder in RecyclerView&lt;/li&gt;
&lt;li&gt;Bind the View&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Just 3 simple steps. Let’s start with 1.&lt;/p&gt;
&lt;h4&gt;1. Create XML Layout for new View Type&lt;/h4&gt;
&lt;p&gt;Create a new XML file res/layout/&lt;strong&gt;item_hero.xml&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;As mentioned above, we will create a header for our list. Mine looks like this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-pagination-tutorial-recyclerview-multiple-view-types/hero-layout-preview.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Hero Layout preview&lt;/p&gt;
&lt;p&gt;Feel free to use your creativity to make a layout you like. But if you want to use mine, you can get the layout file from GitHub.&lt;/p&gt;
&lt;h4&gt;2. Update Item View Types&lt;/h4&gt;
&lt;p&gt;Once your layout is created, we need to tell RecyclerView about it. Open &lt;em&gt;PaginationAdapter.java&lt;/em&gt; and add a flag for our new (header) view type.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class PaginationAdapter extends RecyclerView.Adapter &amp;lt; RecyclerView.ViewHolder &amp;gt; {

 // View Types
 private static final int ITEM = 0;
 private static final int LOADING = 1;
 private static final int HERO = 2;
 ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we need to tell our Adapter about which &lt;code&gt;View&lt;/code&gt; should be displayed when. You do this in the &lt;code&gt;getItemViewType()&lt;/code&gt; method.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; @Override
 public int getItemViewType(int position) {
  if (position == 0) {
   return HERO;
  } else {
   return (position == movieResults.size() - 1 &amp;amp;&amp;amp; isLoadingAdded) ?
    LOADING : ITEM;
  }
 }
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3. Create ViewHolder in RecyclerView&lt;/h4&gt;
&lt;p&gt;Start by creating an inner class for your &lt;code&gt;ViewHolder&lt;/code&gt; in &lt;em&gt;PaginationAdapter&lt;/em&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/**
 * Header ViewHolder
 */
protected class HeroVH extends RecyclerView.ViewHolder {
 private TextView mMovieTitle;
 private TextView mMovieDesc;
 private TextView mYear;
 private ImageView mPosterImg;

 public HeroVH(View itemView) {
  super(itemView);
  // init views
  mMovieTitle = (TextView) itemView.findViewById(R.id.movie_title);
  mMovieDesc = (TextView) itemView.findViewById(R.id.movie_desc);
  mYear = (TextView) itemView.findViewById(R.id.movie_year);
  mPosterImg = (ImageView) itemView.findViewById(R.id.movie_poster);
 }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the &lt;code&gt;ViewHolder&lt;/code&gt; created, we need to inflate it in &lt;code&gt;onCreateViewHolder()&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
 RecyclerView.ViewHolder viewHolder = null;
 LayoutInflater inflater = LayoutInflater.from(parent.getContext());

 switch (viewType) {
  case HERO:
   View viewHero = inflater.inflate(R.layout.item_hero, parent, false);
   viewHolder = new HeroVH(viewHero);
   break;
   ...
 }
 return viewHolder;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4. Bind the View&lt;/h4&gt;
&lt;p&gt;Now that our header &lt;code&gt;ViewHolder&lt;/code&gt; is created, it’s time to bind it. From the name, you would’ve known what I’m talking about. Yes, the &lt;code&gt;onBindViewHolder()&lt;/code&gt; method!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
 Result result = movieResults.get(position); // Movie

 switch (getItemViewType(position)) {

  case HERO:
   final HeroVH heroVh = (HeroVH) holder;

   heroVh.mMovieTitle.setText(result.getTitle());
   heroVh.mYear.setText(formatYearLabel(result));
   heroVh.mMovieDesc.setText(result.getOverview());

   loadImage(result.getBackdropPath())
    .into(heroVh.mPosterImg);
   break;
   ...
 }
}

// Bind method helpers

private String formatYearLabel(Result result) {
 return result.getReleaseDate().substring(0, 4) // we want the year only
  +
  &quot; | &quot; +
  result.getOriginalLanguage().toUpperCase();
}

private RequestBuilder &amp;lt; Drawable &amp;gt; loadImage(@NonNull String posterPath) {
 return GlideApp
  .with(context)
  .load(BASE_URL_IMG + posterPath)
  .centerCrop();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s all there is to it! That wasn’t as complex as you thought, was it? We already have 2 different View Types in play. We just added a third one.&lt;/p&gt;
&lt;p&gt;The pagination logic wasn’t touched. So everything will work as it did, with the addition of a header View.&lt;/p&gt;
&lt;p&gt;Don’t take my word though. Find out yourself with the output below!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Output — Final Result&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/android-pagination-tutorial-recyclerview-multiple-view-types/pagination_multiple_viewtypes_output.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Get the Source Code&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Suleiman19/Android-Pagination-with-RecyclerView/tree/androidx&quot;&gt;View Project on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The key to implementing any successful feature comes down to the basics. It’s the foundation. In the case of Pagination, it came down to implementing the Pagination logic correctly. Once that was done, add-on features were relatively easy to add. Like multiple &lt;code&gt;View&lt;/code&gt; Types!&lt;/p&gt;
&lt;p&gt;I hope with this tutorial, you’ll be able to paginate lists with different &lt;code&gt;View&lt;/code&gt; Types.&lt;/p&gt;
&lt;p&gt;What do you plan to create? Does this cover your use-cases? Tell me in the comments below.&lt;/p&gt;
&lt;p&gt;Lastly, if you loved reading this article, share it with others so they can learn too!&lt;/p&gt;
</content:encoded></item><item><title>Use Empty States to your Advantage - Better User Retention</title><link>https://blog.iamsuleiman.com/empty-states-advantage-user-retention/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/empty-states-advantage-user-retention/</guid><description>Empty States are often neglected and designed last. I don’t blame you though. After all, compared to the main screens, these aren’t important. Right? </description><pubDate>Tue, 25 Jul 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Empty States are often neglected and designed last. I don’t blame you though. After all, compared to the main screens, these aren’t important. Right?&lt;/p&gt;
&lt;p&gt;Sadly, no. The worst that can happen is that users can uninstall your app after first use. Trust me, you don’t want that to happen.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Users who uninstall your app after first-use are most likely to never return.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Mostly, empty state screens are ignored until the app is done. Then, you realize that a particular screen could be empty at some time. So you just throw in a little error message like this and call it a day.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://pttrns.com/applications/258&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;iOS Pages app — I&apos;m not sure where it&apos;s asking me to tap...&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This is NOT okay! Once users reach an empty state screen, they might not know what to do. Or they simply might move on to another screen, or worse, another app.&lt;/p&gt;
&lt;p&gt;The gravity of the situation is worse than you think! Here’s a wake-up call.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The average app mostly loses its entire user base within a few months. - &lt;a href=&quot;https://www.linkedin.com/pulse/losing-80-mobile-users-normal-why-best-apps-do-better-andrew-chen&quot;&gt;Andrew Chen (Growth at Uber, LinkedIn Influencer)&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;First, let’s clarify what an empty state is. Then, we’ll see why it must be given importance. Next, let’s find out when it can occur and how to tackle them. Finally, we’ll see how to design effective Empty States.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;What are Empty States?&lt;/h2&gt;
&lt;p&gt;I’ll spare you the boring book definition here.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Empty State or zero-data state is what a user sees when there is no data to display on-screen.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./empty-states-advantage-user-retention/tumblr_omf7ea0aWw1rdf37to1_1280.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Image credit: &lt;a href=&quot;http://emptystat.es&quot;&gt;emptystat.es&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Why Bother?&lt;/h3&gt;
&lt;p&gt;We need to make sure that users learn the purpose of a particular screen. If it’s a news app, and there is no news to display, tell them why.&lt;/p&gt;
&lt;p&gt;Well, that might sound ironic. But what if the network call fails?&lt;/p&gt;
&lt;p&gt;The reality is that 77% of users will uninstall your app in 3 days. Only the top 10-50 apps are able to break that and keep more users.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./empty-states-advantage-user-retention/android_retention.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;You might say these are extreme statistics but think again.&lt;/p&gt;
&lt;h4&gt;The difficulty of User Retention&lt;/h4&gt;
&lt;p&gt;Let me put that in perspective for you.&lt;/p&gt;
&lt;p&gt;You use apps too right? Say you want to try out a news app. I’m sure you don’t download just one, but at least a couple of them.&lt;/p&gt;
&lt;p&gt;Then, you give each app a try. You try to see which one is good. Finally, you keep what you like and you uninstall the rest.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Users try out a lot of apps but decide which ones they want to ‘stop using’ within the first 3-7 days - Ankit Jain, Google.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Get it? That might happen to your app as well. Hence you need to use everything at your disposal to keep your users.&lt;/p&gt;
&lt;p&gt;Once they start using your app, do your best to make them stay. Empty States are the perfect opportunity to do so.&lt;/p&gt;
&lt;p&gt;Use them to encourage interaction, reinforce your brand and increase user loyalty. I know such terms might sound cheesy. But if you use Empty States correctly, your app adoption rates will be much higher. In other words, that translates to lesser app uninstalls.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The best way to bend the retention curve is to target the first few days of usage, and in particular the first visit - Andrew Chen&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When are most of the empty states visible? During the first few days of using the app.&lt;/p&gt;
&lt;p&gt;Now you know what needs to be done. Let’s see when Empty States can occur and how to best design them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Another user retention technique&lt;/strong&gt; — &lt;a href=&quot;https://blog.iamsuleiman.com/stop-using-loading-spinner-theres-something-better/&quot;&gt;Using Skeleton Screens make your app appear faster&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;When can Empty States occur?&lt;/h2&gt;
&lt;p&gt;Now that we know about Empty States and its importance, let’s see when it can actually occur.&lt;/p&gt;
&lt;p&gt;To put it simply, it occurs whenever there is an absence of data.&lt;/p&gt;
&lt;p&gt;Yes, that’s just straight from the definition, but the exact scenarios are as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;for first-time users&lt;/li&gt;
&lt;li&gt;when an error occurs&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;1. For first-time users&lt;/h3&gt;
&lt;p&gt;Empty States can serve as an onboarding for first-time users. Yes, you don’t have to do those forced carousel-like product tours!&lt;/p&gt;
&lt;p&gt;Let’s take the example of the &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.google.android.keep&amp;amp;hl=en&quot;&gt;Google Keep&lt;/a&gt; Android app. It handles Empty States for first-time users in a unique way.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./empty-states-advantage-user-retention/google_keep_empty_state_starter_content.png&quot; alt=&quot;&quot; title=&quot;Google Keep — Empty State&quot; /&gt;&lt;/p&gt;
&lt;p&gt;It displays ‘starter content’ to familiar users with its app. Typically, when you open a note-taking app, it will be empty. You don’t know how a bunch of notes will appear on-screen. You’ll have to create a couple of them to find out.&lt;/p&gt;
&lt;p&gt;Instead, &lt;em&gt;Google Keep&lt;/em&gt; does that for you. So although you don’t have any notes, Keep creates a few.&lt;/p&gt;
&lt;p&gt;With this, first-time users are educated on 2 things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;how notes work within the app&lt;/li&gt;
&lt;li&gt;learn about the app’s features&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That’s pretty smart, right? It works extremely well for them. We’ll talk more about ‘starter content’ later into this article.&lt;/p&gt;
&lt;p&gt;For apps like notes, email, bookmark managers and others, there is no content, to begin with! Users will have to start adding content manually to populate them. In such apps, having Empty States for first-time users is a sure shot.&lt;/p&gt;
&lt;p&gt;But keep in mind that you have to think about individual screens rather than the entire app.&lt;/p&gt;
&lt;p&gt;For example, a news app might show worldwide news by default on the home screen. So no worries there. Say the news app allows a bookmark feature. That screen would be empty unless users bookmark a news article. So that’s an Empty State too. How would you handle that? Think about it!&lt;/p&gt;
&lt;h3&gt;2. When an error occurs…&lt;/h3&gt;
&lt;p&gt;Now for some apps, even if you’re a new user, there will be some content to display. Say that the app makes an API call to fetch content, and for some reason, it fails.&lt;/p&gt;
&lt;p&gt;When a new user opens your app and goes to the home screen, you don’t want that to happen. It appears very bad. Don’t show a generic error message.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./empty-states-advantage-user-retention/IMG_0005-2.jpg&quot; alt=&quot;&quot; title=&quot;Safari iOS app — No internet state Image credit: tympanus.net&quot; /&gt;&lt;/p&gt;
&lt;p&gt;That is just one scenario. This could happen to ANY screen. Make sure you handle that as well.&lt;/p&gt;
&lt;h4&gt;Tell users why it failed&lt;/h4&gt;
&lt;p&gt;This is perhaps the most important thing to remember. When you’re showing an Empty State in the event of an error, tell users what happened.&lt;/p&gt;
&lt;p&gt;Make sure you tell users what the issue is, without going too technical. For example, let’s assume, your app’s servers overloaded and crashed due to traffic surge. If that’s the scenario, don’t get too technical and spam them with crash logs and error codes. That’s for your developers, not users! An appropriate error message could say “Our servers are currently busy”.&lt;/p&gt;
&lt;p&gt;The Google Chrome browser balances information and detail very well. It even adds a bit of humor to it. It has a brilliant empty state that not only tells us what’s wrong. But also suggests how to fix the problem.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./empty-states-advantage-user-retention/chrome_offline_empty_state.png&quot; alt=&quot;&quot; title=&quot;Android Chrome App — Offline State&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Here’s what Chrome achieves with this design.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A generic error message that everyone can understand&lt;/li&gt;
&lt;li&gt;Suggests steps to resolve the error&lt;/li&gt;
&lt;li&gt;An error code — for the tech savvy?&lt;/li&gt;
&lt;li&gt;Download Page Later button— automatically download page for viewing when the internet is back on&lt;/li&gt;
&lt;li&gt;T-Rex game— it’s actually a game you can play to kill time until your internet comes back&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;FUN FACT:&lt;/strong&gt; &lt;a href=&quot;https://www.quora.com/Why-does-Google-Chrome-show-a-dinosaur-when-you-are-offline&quot;&gt;Why Google Chrome shows a dinosaur when offline?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here’s another example.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./empty-states-advantage-user-retention/empty_states.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://dribbble.com/shots/2530692-Empty-States&quot;&gt;Desk Empty States by YiJing Z — Dribbble&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Remember that not every scenario is the same. This would have already become evident to you. For example, for a retry page load, it makes sense to have a retry button. But what about an email app with an empty Spam screen?&lt;/p&gt;
&lt;p&gt;Now that’s clear, we can see how to actually design it.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;How to Design Empty States&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;To make blank slate useful, consider inserting quick tutorials, videos, help tips, call to action-elements, screenshot of the page when it is in “normal” stage – anything that helps the user and makes him happy with your app. — &lt;a href=&quot;http://patternry.com/p=blank-slate/&quot;&gt;Patternry&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here is a couple of tips on how to design effective Empty States. Let’s go through them one at a time.&lt;/p&gt;
&lt;h3&gt;1. Be informative&lt;/h3&gt;
&lt;p&gt;When an empty state occurs, it is visible to the user. Tell them why they’re seeing this screen.&lt;/p&gt;
&lt;p&gt;When a user sees an empty state, 2 things should be conveyed.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Purpose of the screen (what can I expect to see here?)&lt;/li&gt;
&lt;li&gt;Why am I currently seeing an empty state?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;./empty-states-advantage-user-retention/IMG_0004-e1500915776702.jpg&quot; alt=&quot;&quot; title=&quot;Dropbox favorites Image credit: tympanus.net&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Copy in design is very powerful. It effectively communicates what users need to know. The lesser the words used, the better.&lt;/p&gt;
&lt;p&gt;If you read carefully, the copy answers both those questions above. It tells us:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;What is this screen?&lt;/li&gt;
&lt;li&gt;What’s the use of marking a file as a ‘favorite’?&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2. Handle Failure States— Don’t scare your users&lt;/h3&gt;
&lt;p&gt;If it’s an error, tell them what went wrong. Take it a step further by suggesting how to resolve the error. Remember the &lt;a href=&quot;#img_android_chrome_es&quot;&gt;Google Chrome example&lt;/a&gt;?&lt;/p&gt;
&lt;p&gt;Here’s what you can do with Empty States for an error:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;show a non-technical copy for error text&lt;/li&gt;
&lt;li&gt;suggest possible steps to resolve the error (as simple and short as possible)&lt;/li&gt;
&lt;li&gt;Don’t use technical jargon that can confuse users&lt;/li&gt;
&lt;li&gt;Allow them to reload (retry loading a page)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./empty-states-advantage-user-retention/tumblr_of8y402csR1rdf37to1_1280.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Image credit: &lt;a href=&quot;http://emptystat.es&quot;&gt;emptystat.es&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;3. Encourage Users to take action&lt;/h3&gt;
&lt;p&gt;A simple, yet highly-effective way to get users to interact, is to use a &lt;strong&gt;CTA (Call-to-Action)&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A call-to-action (usually abbreviated as CTA) is an image or line of text that prompts your visitors, leads, and customers to take action. It is, quite literally, a &quot;call&quot; to take an &quot;action.”— &lt;a href=&quot;https://blog.hubspot.com/marketing/what-is-call-to-action-faqs-ht&quot;&gt;blog.hubspot.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In other words, for our apps, CTAs are buttons. Big bold, attention hogging buttons. When a user sees a screen, the should immediately be able to see that CTA (button). That’s what makes it effective.&lt;/p&gt;
&lt;p&gt;Material Design provides us a &lt;a href=&quot;https://material.io/guidelines/components/buttons-floating-action-button.html&quot;&gt;Floating Action Button&lt;/a&gt;. That’s a perfect candidate for a CTA!&lt;/p&gt;
&lt;p&gt;Some examples would be a note-taking app. Prompt first-time users to add a new note by using a CTA button. Or a recipe app, where the CTA is to add a new recipe.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./empty-states-advantage-user-retention/shotter.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://dribbble.com/shots/1738412-Project-empty-state&quot;&gt;Marvel App - Project empty state by Murat Mutlu — Dribbble&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Yet for some screens, there is simply nothing to do. Example, Gmail Spam screen.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./empty-states-advantage-user-retention/android-gmail-spam-empty-state.png&quot; alt=&quot;&quot; title=&quot;Gmail App — Spam&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;4. Display Starter Content&lt;/h3&gt;
&lt;p&gt;Remember the Google Keep app? We spoke about it as an example for Empty States. That’s called Starter Content.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Evernote app — starter content for first-time users&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;With this, 2 goals can be achieved.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Help familiarize users with how notes work&lt;/li&gt;
&lt;li&gt;Use these ‘starter content’ notes to to flaunt the app’s features&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Consider Twitter, where every new user needs to follow few people first to get started. In this way, no first-time user’s home feed is going to be empty. This can also be seen as a way of Twitter reinforcing what it’s all about.&lt;/p&gt;
&lt;h3&gt;5. Stick to your brand— be consistent&lt;/h3&gt;
&lt;p&gt;You might have a lot of freedom when designing Empty States. But make sure you stick to your brand.&lt;/p&gt;
&lt;p&gt;By that I mean, make sure you stick to your styleguide and color palette. The last thing you want is a screen that feels alien within your entire app.&lt;/p&gt;
&lt;p&gt;Alright, this might not be a design tip that’s specific to Empty States. But even so, it is still important. It’s easy to get carried away!&lt;/p&gt;
&lt;p&gt;For example, if your brand color is blue. For the sake of emphasis, don’t make your Empty State’s CTA button red! Agreed that you might want to emphasize an alert or danger. But don’t do it at the cost of inconsistency.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.uplabs.com/posts/course-dashboard-application&quot;&gt;&lt;/a&gt; &lt;a href=&quot;https://www.uplabs.com/posts/course-dashboard-application&quot;&gt;Course Dashboard by Shashank — MaterialUp&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;6. Use Humor&lt;/h3&gt;
&lt;p&gt;Sometimes, humor can play a big role in damping down the seriousness of an issue.&lt;/p&gt;
&lt;p&gt;A great example of using humor in design is Mailchimp. They know how well to design it so that it engages the user.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./empty-states-advantage-user-retention/04-mailchimp-opt.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Mailchimp — what users see after sending a campaign. Image credit: &lt;a href=&quot;https://www.smashingmagazine.com/2016/06/complete-roadmap-building-delightful-onboarding-experience-mobile-app-users/&quot;&gt;smashingmagazine.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So before you use humor, make sure you it’s in the right context. For example, a good place to use it would be content not found screens (empty search results).&lt;/p&gt;
&lt;p&gt;On the contrary, a bad place to use it would be in an error state. Say a failed task. It’s worse if the error was on your part.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Using humour is fun and is a welcome relief. But also think of scenarios when a customer comes to your site to complain, or they have a problem with your product or service. They may not be in the best mood and that humorous message could be a tipping point for a customer to leave permanently. — &lt;a href=&quot;https://www.spotless.co.uk/insights/using-humour-in-ux/&quot;&gt;spotless.co.uk&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://www.uplabs.com/posts/empty-state-concepts-infused-with-personality&quot;&gt;&lt;/a&gt; Empty state concepts infused with personality by Tasnadi Otto — &lt;a href=&quot;https://www.uplabs.com/posts/empty-state-concepts-infused-with-personality&quot;&gt;MaterialUp&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;7. Keep it simple&lt;/h3&gt;
&lt;p&gt;Arriving at the last design tip, this is the most important one to remember.&lt;/p&gt;
&lt;p&gt;With all the tips mentioned above, it’s easy to include everything and go overboard! Don’t do that.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Remember that simple designs are always more effective.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here’s a great empty state interaction. It’s lovely, but it’s also so fancy that if my app is simple and not animation-heavy. I wouldn’t attempt anything like this, just for an Empty State!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.uplabs.com/posts/empty-state-eb2dc951-27ef-4b4c-af8a-c490e01a1431&quot;&gt;&lt;/a&gt; &lt;a href=&quot;https://www.uplabs.com/posts/empty-state-eb2dc951-27ef-4b4c-af8a-c490e01a1431&quot;&gt;Empty State by Jordan Nelson — MaterialUp&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An Empty State is supposed to be a lightweight screen. If there is an action to be performed, make sure it’s just one. Don’t offer many points of interaction on a single empty state! That’s just confusing.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Takeaway&lt;/h2&gt;
&lt;p&gt;To summarize everything, Empty States are an excellent opportunity to engage with users. It might seem insignificant in the larger picture. But even the smallest of things matter.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Attention to detail matters because when you show that you care about the small details, people trust you to care about the big ones. — &lt;a href=&quot;https://ux.shopify.com/empty-states-more-like-you-have-no-idea-how-much-work-goes-into-those-states-amirite-e0102f58b64e&quot;&gt;Meg Robichaud (Shopify UX)&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;User retention with apps are already very hard. So use every chance you have to keep them. Because once they leave, it’s difficult to get them back.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Remember that no screen should be a dead-end for your users.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Wrap up&lt;/h3&gt;
&lt;p&gt;Keeping these simple design tips in mind will help you create effective Empty States:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Be informative&lt;/strong&gt; — tell users why they’re seeing this screen&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Handle failure&lt;/strong&gt; — tell why the error occurred and suggest a fix&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use a CTA&lt;/strong&gt; — encourage users to take action&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Consider Starter Content&lt;/strong&gt; — great way to familiarize users with your app&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Be consistent&lt;/strong&gt; — stick to your brand’s design guidelines&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use Humour&lt;/strong&gt; — reduce the seriousness of an issue. Use carefully&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keep it simple&lt;/strong&gt; — nothing over the top. Remember simple = effective.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I hope this article will help you design better, effective Empty States. Use them to your advantage for better user retention!&lt;/p&gt;
&lt;p&gt;Lastly, if you need some design inspiration, these resources have you covered.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Resources for your inspiration —&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://emptystat.es&quot;&gt;emptystat.es&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pttrns.com/?scid=30&quot;&gt;pttrns.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://ui-patterns.com/patterns/BlankSlate/examples&quot;&gt;ui-patterns.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks for reading!&lt;/p&gt;
</content:encoded></item><item><title>Customize Color with Styled Google Maps in Android</title><link>https://blog.iamsuleiman.com/styled-google-maps-customize-color-android/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/styled-google-maps-customize-color-android/</guid><description>You can now style and customize your Google Maps colors and more. In this Android tutorial, let’s see how we can do that in our apps. Google Maps has </description><pubDate>Tue, 04 Jul 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;You can now style and customize your Google Maps colors and more. In this Android tutorial, let’s see how we can do that in our apps. Google Maps has added this ability across all platforms. This means regardless of whether you use Google Maps for Web, iOS or Android, you’ll be able to style them. By default, Google Maps looks like this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./styled-google-maps-customize-color-android/Screen-Shot-2017-07-03-at-8.34.38-PM.png&quot; alt=&quot;&quot; title=&quot;Default Google Maps&quot; /&gt;&lt;/p&gt;
&lt;p&gt;We’re all used to this and by no means am I saying it looks bad. But say I want to display a map that corresponds to my brand color scheme.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./styled-google-maps-customize-color-android/desktop_hd_copy_15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://dribbble.com/shots/3136953-Directions-Module&quot;&gt;Directions Module by David Rodriguez&lt;/a&gt; Now imagine if my only option was to display the default Google maps, with it&apos;s default colors. It wouldn&apos;t go well with the design, would it? The color scheme of the map won&apos;t be in harmony with the rest of the design. In other words, it sticks out, like a sore thumb. In such scenarios, we need a map that reflects our brand theme. Our brand color palette. This wasn’t possible before. But now, Google allows Styled maps. Using this, we can customize the map to look the way we want. This includes modifying colors, with a very high degree of control.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;We’ll start by creating a new Android Studio project. Thankfully, we have pre-defined templates (for Activities) to start with. &lt;a href=&quot;https://blog.iamsuleiman.com/image-gallery-app-android-studio-1-4-glide/&quot;&gt;Activity templates were introduced in Android Studio 1.4&lt;/a&gt;. So when you create a new project, chose the ‘Google &lt;em&gt;Maps Activity&lt;/em&gt;’ template.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./styled-google-maps-customize-color-android/new-project-map-activity.png&quot; alt=&quot;&quot; title=&quot;Android Studio - Activity Templates&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Here are the project settings:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;minSdkVersion - 14&lt;/li&gt;
&lt;li&gt;targetSdkVersion - 26&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks to this, we don’t have to spend a lot of time configuring the Maps SDK and whatnot. I remember the first time I tried using Maps in Android (back in 2012). It took me well over an hour to simply display a Map! But you don’t have to worry anymore as we’ve come a long way from that!&lt;/p&gt;
&lt;h3&gt;Configuring Google Maps&lt;/h3&gt;
&lt;p&gt;Once the project has loaded, Android Studio will open the &lt;strong&gt;google_maps_api.xml&lt;/strong&gt; file by default.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./styled-google-maps-customize-color-android/maps_api_xml-file-comments.png&quot; alt=&quot;&quot; title=&quot;Auto-generated maps_api.xml&quot; /&gt;&lt;/p&gt;
&lt;p&gt;You’ll notice there is one step to follow to get your Google Maps API Key. Trust me, this is nothing compared to the amount of steps earlier! So follow the comments on the file. Don’t worry, I’ll still walk you through them. but you’ll have to grab the URL and keys from the google_maps_api.xml file’s comments.&lt;/p&gt;
&lt;h4&gt;1. Go to the URL provided - &lt;em&gt;&lt;a href=&quot;http://console.developers.google.com&quot;&gt;console.developers.google.com&lt;/a&gt;&lt;/em&gt;&lt;/h4&gt;
&lt;p&gt;You’ll land on a page like this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./styled-google-maps-customize-color-android/dev-console-new-project.png&quot; alt=&quot;&quot; title=&quot;Create a new project in Google Developer Console&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Select ‘Create a Project’ from the dropdown and then hit the Continue button.&lt;/p&gt;
&lt;h4&gt;2. Create Google Maps API Key&lt;/h4&gt;
&lt;p&gt;In the next step (screen), click the ‘Create API Key’ button.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./styled-google-maps-customize-color-android/dev-console-creating-api-key.png&quot; alt=&quot;&quot; title=&quot;Creating new API key...&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;3. Get your generated API Key&lt;/h4&gt;
&lt;p&gt;Google now generated your Maps API key. So copy it and paste it in your XML file for the string name ‘google_maps_key’. Replace the ‘YOUR_KEY_HERE’ with your actual API key! You can optionally set up API Key restrictions if you want (see screenshot above). It’s fairly simple. Click restrictions and you’ll get a screen like this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./styled-google-maps-customize-color-android/dev-console-key-restrictions.png&quot; alt=&quot;&quot; title=&quot;Generated API key restrictions&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Choose ‘Key restriction’ as ‘Android Apps’ and hit Save button. Note that you don’t have to bother about the Package name and SHA-1 certificate fingerprint. You’ll realize that the fingerprint is same as the one in your Android Studio project comments. In other words, Google took care of that for you too. Sweet? Now let’s move on. With our API key in place, we’re finally ready to use Google Maps. But before we get to styling, let’s check if Maps itself works. So run your app and check it out. It’s always better to test every step of the way. Otherwise, you’ll never know what went wrong where. &lt;strong&gt;NOTE:&lt;/strong&gt; Google Maps needs Google Play Services to work. So it’s safe to always run the app on a real device. Or, you can configure and use an AVD that includes Google APIs with Play Services. Here’s how Google Maps loads on my phone.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./styled-google-maps-customize-color-android/google-maps-first-test.png&quot; alt=&quot;&quot; title=&quot;Default Google Maps - Android&quot; /&gt;&lt;/p&gt;
&lt;p&gt;It works just fine. So let’s finally move on to styling it.&lt;/p&gt;
&lt;h5&gt;Using Styled Maps&lt;/h5&gt;
&lt;p&gt;Google Maps can load styling options via two different formats: &lt;strong&gt;1 - JSON file&lt;/strong&gt; You load the JSON file in the onMapReady() method.&lt;/p&gt;
&lt;p&gt;@Override
public void onMapReady(GoogleMap googleMap)
{
try {
// Customise map styling via JSON file
boolean success = googleMap.setMapStyle( MapStyleOptions.loadRawResourceStyle( this, R.raw.style_map_json));&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    if (!success) {
        Log.e(TAG, &quot;Style parsing failed.&quot;);
    }
} catch (Resources.NotFoundException e) {
    Log.e(TAG, &quot;Can&apos;t find style. Error: &quot;, e);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;String resource Using a string resource works in a similar way.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;@Override
public void onMapReady(GoogleMap googleMap) {
try {
// Customise map styling via String resource
boolean success = googleMap.setMapStyle(new MapStyleOptions(getResources() .getString(R.string.style_json)));&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    if (!success) {
        Log.e(TAG, &quot;Style parsing failed.&quot;);
    }
} catch (Resources.NotFoundException e) {
    Log.e(TAG, &quot;Can&apos;t find style. Error: &quot;, e);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we know how to load our Map styles. But how do we actually create our style? Let’s look at that next.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Creating a Color Theme for Google Maps&lt;/h2&gt;
&lt;p&gt;I’ll put it bluntly. There are two ways you can go about it. One, write a JSON file. Manually writing every property (do you even know them?). Or two, using the Map Styling Wizard. In other words, save yourself time and frustration. Go with the second option. Use the Styling Wizard. It’s a no-brainer. Seriously!&lt;/p&gt;
&lt;h3&gt;Google Maps Styling Wizard&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./styled-google-maps-customize-color-android/google-maps-styling-wizard.png&quot; alt=&quot;&quot; title=&quot;Welcome to Google Maps Styling Wizard&quot; /&gt;&lt;/p&gt;
&lt;p&gt;For this part, you just play around with the Styling Wizard. Adjust the density of features depending on how much detail you want on the map. Then select a basic, pre-defined theme to work with. Finally, you can click on ‘MORE OPTIONS’ to alter the properties of each Map object. Trust me, there’s a LOT of things you can customize that it’s easy to get lost.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./styled-google-maps-customize-color-android/styling-wizard-more-options.png&quot; alt=&quot;&quot; title=&quot;Abundant customization options in Map Styling Wizard&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I’ve chosen very light, pastel-like colors for the map. These are colors mainly for the terrain, parks, water and highways. Once you’re done, click the FINISH button. Next, copy the JSON from the popup that appears.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./styled-google-maps-customize-color-android/styling-wizard-json.png&quot; alt=&quot;&quot; title=&quot;Auto-generated JSON from Styling Wizard&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Head over to your Android Studio project and create a new file under &lt;em&gt;Project/app/src/main/res/raw/&lt;strong&gt;maps.style.json&lt;/strong&gt;&lt;/em&gt;. This JSON file is where we’ll paste the JSON copied from the Maps Style Wizard. Now all that’s left is to tell Google Maps to load its style from this JSON file. Remember we spoke about how to do this in the &lt;code&gt;onMapReady()&lt;/code&gt; method? Let me remind you again. Now that we have our JSON file ready, we can call it in like this. Open &lt;strong&gt;MapsActivity.java&lt;/strong&gt; and go to the &lt;code&gt;onMapReady()&lt;/code&gt; method. The template has this method already implemented for you. So with the default template existing, here’s how to load the Styled Map.&lt;/p&gt;
&lt;p&gt;@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
try {
boolean success = mMap.setMapStyle(
MapStyleOptions.loadRawResourceStyle(
this, R.raw.maps_style));&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    if (!success) {
        Log.e(TAG, &quot;Style parsing failed.&quot;);
    }
} catch (Resources.NotFoundException e) {
    Log.e(TAG, &quot;Can&apos;t find style. Error: &quot;, e);
}
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;It’s actually just one line of code. The try catch block just makes it look verbose. With Styled Maps now loaded, run your app and check it.&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;Styled Maps - Output&lt;/h4&gt;
&lt;p&gt;Based on the colors I chose against a Grey- themed Google Map, mine looks like this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./styled-google-maps-customize-color-android/styled-maps-output.png&quot; alt=&quot;&quot; title=&quot;My custom styled Google Maps&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I changed parks to purple color. Just so I visually know that Styled maps are working. I know it’s an ugly map. But I’m sure you can do better!&lt;/p&gt;
&lt;h5&gt;Wrap Up&lt;/h5&gt;
&lt;p&gt;In this Android tutorial, we saw how to Style our default-looking Google Maps. First, we created an Android Studio project, using the Maps Activity template. We then created an API key to use with Maps. Next, we used the Maps Styling Wizard to configure Google Maps to our liking. Then, we pasted the generated JSON over to our project. Finally, we told Google Maps to load its styling from that JSON file.&lt;/p&gt;
&lt;h6&gt;Where to from here?&lt;/h6&gt;
&lt;p&gt;That’s all there is to it! With Styled maps, it is now possible to customize Google Maps to be more relevant to your app color-scheme. No more out-of-place looking Maps. If used properly they can now blend well with your UI designs. How are you going to customize your map? I’m very interested to see what you’ll come up with. Show me in the comments below. &lt;em&gt;Header Image Credits:&lt;/em&gt; &lt;a href=&quot;https://dribbble.com/shots/3184356-Robin-Maps&quot;&gt;Asar Morris&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Android O Tutorial: Supporting Picture-in-Picture (PIP)</title><link>https://blog.iamsuleiman.com/android-o-tutorial-picture-in-picture-pip/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/android-o-tutorial-picture-in-picture-pip/</guid><description>Picture in Picture or PIP is a feature famously seen on YouTube and Android TV apps. It minimizes your content (typically video), keeping it pinned to</description><pubDate>Thu, 22 Jun 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Picture in Picture or PIP is a feature famously seen on YouTube and Android TV apps. It minimizes your content (typically video), keeping it pinned to a corner while you carry out your other tasks. In other words, the video keeps playing in the corner, while you continue using the app.&lt;/p&gt;
&lt;h2&gt;What&apos;s Picture-in-Picture?&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Picture-in-picture mode lets apps run a video activity in the pinned window while another activity continues in the background. - &lt;a href=&quot;http://developer.android.com&quot;&gt;developer.android.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let me rephrase that for you. Open YouTube and watch a video. You&apos;ll notice you can minimize that video and continue to watch it whilst using the app.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/android-o-tutorial-picture-in-picture-pip/youtube-picture-in-picture-pip.gif&quot; alt=&quot;&quot; title=&quot;PIP in YouTube app&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Recently, even Facebook added it. You can minimize a video and continue watching it, while you&apos;re scrolling through your newsfeed. Sweet!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-o-tutorial-picture-in-picture-pip/facebook_pip.png&quot; alt=&quot;&quot; title=&quot;PIP in Facebook&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Until now, to implement such a feature, Android Developers like you and I had two options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Write our own - won&apos;t come off pretty&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/pedrovgs/DraggablePanel&quot;&gt;DraggablePanel&lt;/a&gt; - works fine&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Yep, I heard you. DraggablePanel was our only choice. While that was and is a fine library, I&apos;d say there&apos;s a better option today.&lt;/p&gt;
&lt;h2&gt;Picture in Picture with Android O&lt;/h2&gt;
&lt;p&gt;When Android Nougat came, we saw PIP support for Android TV. It was only a matter of time when it came to mobile. Finally, in the next version, Android O added support for mobile too! In this article, I&apos;ll tell you how to enable support for mobile. Developers who have worked on Android TV with Nougat should feel right at home. But don&apos;t worry if you haven&apos;t. You&apos;ll be able to follow along just as easy.&lt;/p&gt;
&lt;h3&gt;Getting Started - Project Setup&lt;/h3&gt;
&lt;p&gt;To use all of Android O’s features properly, you need Android Studio 3.0 Preview. This works as a standalone install compared to your existing, stable Android Studio. If you already have all of that setup, then feel free to go ahead with this tutorial. If you haven’t setup Android Studio 3.0 Preview, I strongly recommend you go through the &lt;a href=&quot;https://blog.iamsuleiman.com/android-o-what-developers-need-know/&quot;&gt;Android O: Getting Started article&lt;/a&gt; first. It covers how to setup Android Studio Preview to use API 26. Anyways, for your reference, here’s what we’ll be using:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Android Studio 3.0 Preview&lt;/li&gt;
&lt;li&gt;Gradle version - 3.0.0-alpha4&lt;/li&gt;
&lt;li&gt;compileSdkVersion - 26&lt;/li&gt;
&lt;li&gt;buildToolsVersion - 26.0.0&lt;/li&gt;
&lt;li&gt;Support Library Version - 26.0.0-beta2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can use these to update your Gradle build accordingly. Lastly, make sure you’re using Google’s maven repository. Open your project-level &lt;em&gt;build.gradle&lt;/em&gt; file.&lt;/p&gt;
&lt;p&gt;buildscript {
repositories {
&lt;strong&gt;google()&lt;/strong&gt;
jcenter()
}
dependencies {
classpath &apos;com.android.tools.build:gradle:3.0.0-alpha4&apos;
}
}&lt;/p&gt;
&lt;p&gt;allprojects {
repositories {
** google()**
jcenter()
}
}
// ...&lt;/p&gt;
&lt;h4&gt;Adding PIP Support on Android&lt;/h4&gt;
&lt;p&gt;First, we need to create an &lt;code&gt;Activity&lt;/code&gt; and declare that it supports picture-in-picture. So go ahead and create a new &lt;code&gt;Activity&lt;/code&gt;. I call mine &lt;strong&gt;PipActivity.java&lt;/strong&gt;. Next, open your &lt;em&gt;AndroidManifest.xml&lt;/em&gt;. Here, we’ll declare that &lt;em&gt;PipActivity&lt;/em&gt; supports Picture-in-Picture. We do so by using the &lt;code&gt;supportsPictureInPicture&lt;/code&gt; attribute.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Developers who have worked with Android Nougat for TV might notice that the &lt;code&gt;resizeableActivity&lt;/code&gt; attribute is no longer required for PIP. However, keep in mind that if you set &lt;code&gt;resizeableActivity&lt;/code&gt; to false, then the &lt;code&gt;supportsPictureInPicture&lt;/code&gt; attribute is ignored.&lt;/p&gt;
&lt;h5&gt;Handling Activity Duplication and Recreation&lt;/h5&gt;
&lt;p&gt;Notice the &lt;code&gt;launchMode&lt;/code&gt; attribute in the Manifest. Any guesses why it’s required? &lt;strong&gt;Avoiding Activity Duplication - Using Launch Modes&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Launch Mode &lt;em&gt;&lt;strong&gt;singleTask&lt;/strong&gt;&lt;/em&gt; tells Android that there should be only one instance of that Activity.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In other words, if I keep starting &lt;em&gt;PipActivity&lt;/em&gt;, only one instance of it should open. There should never be any duplicates. This scenario is highly likely and is mandatory that you handle it. For example, take the YouTube app. You’re browsing through a playlist and you open a particular video. Then, if you enter PIP mode, you’re back to the playlist screen. Now, if you click the same video again, we want the existing video to enlarge back up. Or, if you click another video, we want PIP to maximize with the clicked video playing. We do not want another (PIP) screen to open. The &lt;em&gt;singleTask&lt;/em&gt; Launch Mode handles this for us. &lt;strong&gt;Preventing Activity Recreation&lt;/strong&gt; If you’re that daring person who wants to support PIP and orientation changes, then you’ll need one extra attribute. Add the &lt;strong&gt;configChanges&lt;/strong&gt; attribute to your Manifest to prevent &lt;em&gt;PipActivity&lt;/em&gt; from being recreated each time on orientation change. This will be extremely handy when your PiP includes a player (which will most likely be the scenario).&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Starting Picture-in-Picture mode&lt;/h2&gt;
&lt;p&gt;Now that we’ve prepared our &lt;code&gt;Activity&lt;/code&gt;, the next step is to trigger PIP mode. So to do that, we need to create a simple layout first. Open your Activity’s XML layout.&lt;/p&gt;
&lt;h3&gt;XML Layout&lt;/h3&gt;
&lt;p&gt;Honestly, I leave this to your imagination. But for the sake of this tutorial, I’m going to pretend we have a UI that includes a player.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-o-tutorial-picture-in-picture-pip/android_o_pip_layout.png&quot; alt=&quot;&quot; title=&quot;PIP XML layout&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The layout is very simple. Here’s the XML code for the same.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;ImageButton
    android:id=&quot;@+id/btn_minimize&quot;
    android:layout_width=&quot;wrap_content&quot;
    android:layout_height=&quot;wrap_content&quot;
    android:layout_gravity=&quot;top|start&quot;
    android:layout_margin=&quot;@dimen/layout_margin&quot;
    android:background=&quot;?selectableItemBackgroundBorderless&quot;
    android:src=&quot;@drawable/ic_picture_in_picture_alt_black_24dp&quot;
    android:tint=&quot;@android:color/white&quot; /&amp;gt;

&amp;lt;!--Other Player UI here--&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!--Video details UI here--&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In short, we have a &lt;code&gt;FrameLayout&lt;/code&gt; that would be our player. We also have a button that indicates switching to Picture in Picture mode. You can add that icon via a right click on &lt;em&gt;res/drawable folder&amp;gt; New&amp;gt; Vector Asset&lt;/em&gt;. In this way, you can choose from the entire set of Google’s Material Design icons.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TIP:&lt;/strong&gt; These icons that you import are by default, black in color. So make sure to &lt;a href=&quot;https://blog.iamsuleiman.com/tint-icons-in-android/&quot;&gt;tint vector icons for pre-Lollipop devices&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Triggering PIP&lt;/h4&gt;
&lt;p&gt;With the layout complete, it’s now time to start Picture-in-Picture. So to do that, head over to &lt;em&gt;PipActivity&lt;/em&gt;. PiP is triggered when we click the button on the top-right. So we’ll write our entire logic inside that button’s click listener.&lt;/p&gt;
&lt;p&gt;mBtnPip.setOnClickListener(view -&amp;gt; {
if (android.os.Build.VERSION.SDK_INT &amp;gt;= 26) {
//Trigger PiP mode
try {
Rational rational = new Rational(mFramePlayer.getWidth(),
mFramePlayer.getHeight());&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;            PictureInPictureParams mParams =
                    new PictureInPictureParams.Builder()
                            .setAspectRatio(rational)
                            .build();

           ** enterPictureInPictureMode(mParams);**
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
    } else {
        Toast.makeText(PipActivity.this, &quot;API 26 needed to perform PiP&quot;, Toast.LENGTH_SHORT).show();
    }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are a couple of things going on here, so let’s tackle it one at a time. If you’ve seen the PIP animation, notice that the ‘ratio’ the player maintains when maximized and minimized, are the same. So it’s essential that we do the same. You can simply enter Picture-in-Picture mode using &lt;code&gt;enterPictureInPictureMode()&lt;/code&gt;. But you can pass in some optional parameters if you wish. That’s what we’re doing here. We will maintain the ratio of our dummy player to be the same in PIP mode. For that, we need to pass a &lt;code&gt;PictureInPictureParams&lt;/code&gt; object.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; I’m triggering PIP mode only for API 26 and above. Ideally, as a fallback, you must hide or disable this feature. For the sake of this tutorial, I’m displaying a &lt;code&gt;Toast&lt;/code&gt; message.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Best Practices&lt;/h3&gt;
&lt;p&gt;Now that we’ve seen how to launch PIP, there are a couple of things to keep in mind.&lt;/p&gt;
&lt;h4&gt;Adapting UI to PIP mode&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;When in PIP mode, avoid displaying any UI controls except the video player.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When &lt;em&gt;PipActivity&lt;/em&gt; enters PIP mode, we need to hide everything displayed except the video. So to do that, we need some way to know that we’re currently in PIP. We can detect when an &lt;code&gt;Activity&lt;/code&gt; enters Picture-in-Picture using the &lt;code&gt;onPictureInPictureModeChanged()&lt;/code&gt; method. In our case, the only UI control we need to hide is the PIP &lt;code&gt;ImageButton&lt;/code&gt; on the top-left.&lt;/p&gt;
&lt;p&gt;@Override
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
super.onPictureInPictureModeChanged(isInPictureInPictureMode);
if (!isInPictureInPictureMode) {
mBtnPip.setVisibility(View.VISIBLE);
} else {
mBtnPip.setVisibility(View.GONE);
}
}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TIP:&lt;/strong&gt; You can override &lt;code&gt;onPictureInPictureModeChanged()&lt;/code&gt; either in your &lt;code&gt;Activity&lt;/code&gt; or &lt;code&gt;Fragment&lt;/code&gt;.&lt;/p&gt;
&lt;h4&gt;Updating PIP Content&lt;/h4&gt;
&lt;p&gt;Remember we discussed the importance of &lt;code&gt;singleTask&lt;/code&gt; Launch Mode to avoid duplicate PIPs? I even used the YouTube app as an example. If you think carefully about that example, there’s one thing that we don’t know how to handle. When we’re in PIP, and we click on another content, we solved the duplication problem. But PIP must be updated with the content that we clicked. How can we do that? Use the &lt;code&gt;onNewIntent()&lt;/code&gt; method to update your PIP with the new content data.&lt;/p&gt;
&lt;h4&gt;Managing Playback&lt;/h4&gt;
&lt;p&gt;Once our &lt;code&gt;Activity&lt;/code&gt; goes into PIP mode, we need to ensure that the content playback continues.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; When you switch to PIP mode, Android considers that &lt;code&gt;Activity&lt;/code&gt; to be in a paused state. Hence it calls that Activity’s &lt;code&gt;onPause()&lt;/code&gt; method.&lt;/p&gt;
&lt;p&gt;Forget PIP for a second. If your &lt;code&gt;Activity&lt;/code&gt; goes into &lt;code&gt;onPause()&lt;/code&gt;, then ideally, you’ll pause your playback too. But if you’re in PIP mode, make sure you don’t pause playback. Android’s given us a handy method &lt;code&gt;isInPictureInPictureMode()&lt;/code&gt; that we can use to handle this.&lt;/p&gt;
&lt;p&gt;@Override
protected void onPause() {
super.onPause();&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (Build.VERSION.SDK_INT &amp;gt;= Build.VERSION_CODES.N
        &amp;amp;&amp;amp; isInPictureInPictureMode()) {
    // Continue playback...
}
// Not in PIP &amp;amp; Activity is paused. Pause playback if required....
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Output&lt;/h2&gt;
&lt;p&gt;Finally, we’ve done everything that’s needed to make Picture in Picture work. We’ve also made sure to handle its common scenarios. Let’s see how it works. Make sure you create an Android Emulator (AVD) that runs API 26 (Google Play System Image). Once you’ve done that, run your app. You should get a working PIP like this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/android-o-tutorial-picture-in-picture-pip/android_o_pip_animation.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Wrap up&lt;/h3&gt;
&lt;p&gt;Picture-in-Picture was finally brought to Android Smartphones thanks to Android O. In this article, we briefly saw how to prepare Android Studio to use the latest Android O SDK (API 26). Then we learnt how to use PIP. Although PIP is generally used for video playing content, this tutorial excluded a guide for video playing. This was done to ensure the focus stays on Picture in Picture. &lt;strong&gt;SOURCE CODE:&lt;/strong&gt; &lt;a href=&quot;https://github.com/Suleiman19/Android-O-Sample/blob/master/app/src/main/java/com/iamsuleiman/androido/PipActivity.java&quot;&gt;Sample working Project available on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Where to from here?&lt;/h4&gt;
&lt;p&gt;Remember, there is no hard and fast rule that PIP must only be used for video playing content. Its usage is only restricted to your imagination. How will you use PIP in your app? Have any questions? Let me know in the comments below. Lastly, if you liked reading this, don’t forget to share (on the left). If you want updates on the next article, subscribe below.&lt;/p&gt;
</content:encoded></item><item><title>Mega Guide to Android&apos;s Material Design Components</title><link>https://blog.iamsuleiman.com/mega-guide-android-material-design-components/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/mega-guide-android-material-design-components/</guid><description>Material Components are a set of UI components that helps you build Android apps with Material Design. In this post, I&apos;ll cover every Material Design </description><pubDate>Tue, 30 May 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Material Components are a set of UI components that helps you build Android apps with Material Design.&lt;/p&gt;
&lt;p&gt;In this post, I&apos;ll cover every Material Design component available to us. In addition to components, popular design patterns can be recreated as well. That too, quite easily. For example, the &apos;Collapsing App Bar on scroll&apos; (Read as Flexible Space with Image Pattern).&lt;/p&gt;
&lt;p&gt;Moreover, I&apos;ll tell you how to use each Material Component with links to detailed Android tutorials.&lt;/p&gt;
&lt;p&gt;This article has been updated for AndroidX!&lt;/p&gt;
&lt;h2&gt;A Brief History&lt;/h2&gt;
&lt;p&gt;Material Design was introduced in 2014. At that time, there was little to no official support from Google for us Android Developers.&lt;/p&gt;
&lt;p&gt;On one hand, we had Material Design in all its vibrancy, robust principles and eye-catching animations. On the other hand, we didn’t receive any official support on how to implement all of that.&lt;/p&gt;
&lt;p&gt;But all that changed gradually over a year.&lt;/p&gt;
&lt;p&gt;Support libraries steadily improved. AppCompat supported basic color theming. Even common widgets were ‘Materialized’. They were also made backward-compatible.&lt;/p&gt;
&lt;p&gt;But Material Design wasn&apos;t just about a UI overhaul and vibrancy, was it?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Motion provides meaning. It respects and reinforces the user as the prime mover. Motion is meaningful and appropriate, serving to focus attention and maintain continuity…&lt;/p&gt;
&lt;p&gt;– &lt;a href=&quot;https://material.io/guidelines/material-design/introduction.html#introduction-principles&quot;&gt;Material Design Principles&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Material Components&lt;/h3&gt;
&lt;p&gt;Now, Android has modularized and put all their Material Design related offerings into a single resource. They call it &lt;strong&gt;Material Components&lt;/strong&gt;. Here&apos;s their website.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./mega-guide-android-material-design-components/material-design-components-website.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://material.io/components/&quot;&gt;material.io/components&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For those who don&apos;t know, Material Components isn&apos;t another fancy new library. In fact, it&apos;s the same library which we&apos;re already familiar with, packaged in a different offering. Very smart on Google&apos;s part.&lt;/p&gt;
&lt;p&gt;You might have already guessed what it is. For Android, it&apos;s nothing but the Design Support Library.&lt;/p&gt;
&lt;h4&gt;The Real Hero - Design Support Library&lt;/h4&gt;
&lt;p&gt;This gem beat every other library before it. Popular design patterns that took days and hundreds of lines of code were accomplished in a matter of minutes.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;With a little help from the new Android Design Support Library, we’re bringing a number of important material design components to all developers and to all Android 2.1 or higher devices - &lt;a href=&quot;https://android-developers.googleblog.com/2015/05/android-design-support-library.html&quot;&gt;android-developers.googleblog.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Popular Material Design Components such as Snackbar, FAB, Navigation Drawer and more could be easily used. Moreover, patterns like Quick Return, Collapsing Headers were made possible, all through XML. All it takes is one line to enable the animation. That’s brilliance, at its finest!&lt;/p&gt;
&lt;p&gt;You can start using Material Components by adding AndroidX and the Material Components library to your &lt;em&gt;app/build.gradle&lt;/em&gt; file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dependencies {
    …
    implementation &apos;androidx.appcompat:appcompat:1.1.0&apos;
    implementation &apos;com.google.android.material:material:1.0.0&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;Benefits:&lt;/h5&gt;
&lt;p&gt;&lt;strong&gt;1. Ease of use&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;All Material Components can be easily used just like any normal UI widget in Android. Moreover, as I mentioned above, performing on-scroll animations takes only one line of XML. You don&apos;t even have to touch Java.&lt;/p&gt;
&lt;p&gt;I&apos;ll show you how to do all of this, later in this article.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Backward Compatibility&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Remember how we all struggled with maintaining consistency using Material Design? I remember it, crystal clear. Doing anything Material, pre-Lollipop was a nightmare!&lt;/p&gt;
&lt;p&gt;But the Design Support Library offers is compatible back to Android 2.1. Sweet!&lt;/p&gt;
&lt;p&gt;Honestly, the only difference I see is the lack of elevation (depth) on pre-Lollipop. But there&apos;s a simple fix for that too. There&apos;s &lt;a href=&quot;https://blog.iamsuleiman.com/add-a-toolbar-elevation-on-pre-lollipop/&quot;&gt;a way to show elevation shadows on pre-Lollipop&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Respects Material Design Guidelines&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The library is officially by Google&apos;s Android team. All components strictly follow and respect Material Design guidelines. Each Material Component looks and behaves the way it&apos;s supposed to. So you don&apos;t have to worry about anything that may be amiss.&lt;/p&gt;
&lt;p&gt;Also, you can easily &lt;a href=&quot;https://blog.iamsuleiman.com/tint-icons-in-android/&quot;&gt;tint your Material Component to match your brand color&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Material Components - Index&lt;/h2&gt;
&lt;p&gt;The Design Support Library gives us a many to use components. We can even style them to match our brand theme. Here&apos;s a list of all the Material components it offers for us Android developers to use.&lt;/p&gt;
&lt;p&gt;You can treat this list as an index to navigate this entire article.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Important Classes&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#CoordinatorLayout&quot;&gt;CoordinatorLayout&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#Behavior&quot;&gt;Behaviors&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Android Material UI Components&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#bottom-bar-nav&quot;&gt;Bottom Bar Navigation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#bottom-sheet&quot;&gt;Bottom Sheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#floating-action-button&quot;&gt;Floating Action Button (FAB)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#floating-label-edittext&quot;&gt;Floating labels (for EditText)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#material-design-tabs&quot;&gt;Material Design Tabs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#navigation-drawer&quot;&gt;Navigation Drawer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#snackbar&quot;&gt;Snackbar&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Animations&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#quick-return&quot;&gt;Quick Return&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#flexible-space&quot;&gt;Flexible Space with Image&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#parallax-scrolling&quot;&gt;Parallax Scrolling (header)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This post is a one stop destination for you to know about everything this library can do for you. Additionally, I’ll even tell you how to implement each feature.&lt;/p&gt;
&lt;p&gt;Now that you have a glimpse of what we&apos;re going to cover, let&apos;s dive in.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Important Classes&lt;/h2&gt;
&lt;p&gt;Before we get to the Material Components, there are 2 fundamental classes you need to know. Without understanding these, it&apos;s difficult to learn how to use almost any Material Component.&lt;/p&gt;
&lt;h3&gt;1. CoordinatorLayout&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;CoordinatorLayout&lt;/code&gt; is a super-powered &lt;a href=&quot;https://developer.android.com/reference/android/widget/FrameLayout.html&quot;&gt;&lt;code&gt;FrameLayout&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;– &lt;a href=&quot;https://developer.android.com/reference/android/support/design/widget/CoordinatorLayout.html&quot;&gt;Android docs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The &lt;code&gt;CoordinatorLayout&lt;/code&gt; acts as a top-level parent layout. It helps &apos;coordinate&apos; the behaviors of its child Views. One child Views can listen and react to changes based on another child View. The on-scroll animations that the library helps you perform, is because of the &lt;code&gt;CoordinatorLayout&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To be specific, the CoordinatorLayout does this by using &lt;strong&gt;Behaviors&lt;/strong&gt;. This brings us to our next point.&lt;/p&gt;
&lt;h3&gt;2. Behavior&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Behavior&lt;/code&gt; enables interactions for child Views of &lt;code&gt;CoordinatorLayout&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In other words, Behaviors allow you to intercept different events of a child &lt;code&gt;View&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Want your FAB to shrink and grow? Want your &lt;code&gt;Toolbar&lt;/code&gt; to scroll on and off-screen? All that is possible with Behaviors. Most of the interactions that you see in the Design Support, is made with Behaviors.&lt;/p&gt;
&lt;p&gt;Android provides a few default Behaviors off the bat. You&apos;ll become familiar with them as you read this article. However, you can even write our own custom Behavior if you wish.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;
Ian Lake has a brilliant &lt;a href=&quot;https://medium.com/google-developers/intercepting-everything-with-coordinatorlayout-behaviors-8c6adc140c26&quot;&gt;Medium write-up about Behaviors&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Or, if you want to create some amazing animation like the one above, &lt;a href=&quot;https://saulmm.github.io/mastering-coordinator#custom-behaviors&quot;&gt;Saúl Molinero has a great tutorial on Custom Behaviors&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Android Material UI Components&lt;/h2&gt;
&lt;p&gt;The Design Support library offers many UI components out of the box. While the &lt;code&gt;Toolbar&lt;/code&gt; was introduced with the AppCompat Support Library, Design Support offers a wealth of Material Design components.&lt;/p&gt;
&lt;h3&gt;1. Bottom Bar Navigation&lt;/h3&gt;
&lt;p&gt;The newest addition to the Material Design guidelines is Bottom Navigation. Quite recently, it was added to the Design Support Library.&lt;/p&gt;
&lt;p&gt;iOS devs would come to know this as the &lt;code&gt;TabBar&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Bottom navigation bars make it easy to explore and switch between top-level views in a single tap.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./mega-guide-android-material-design-components/bottom_navigation_bar_instagram.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Bottom Bar Navigation as seen on Instagram&lt;/p&gt;
&lt;p&gt;To use Bottom Navigation, you use the &lt;code&gt;BottomNavigationView&lt;/code&gt; class. Here&apos;s a quick code snippet you can drop into your layout.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;com.google.android.material.bottomnavigation.BottomNavigationView
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_gravity=&quot;bottom&quot;
        app:itemBackground=&quot;?attr/colorPrimary&quot;
        app:itemIconTint=&quot;@drawable/selector_bottombar&quot;
        app:itemTextColor=&quot;@drawable/selector_bottombar&quot;
        app:menu=&quot;@menu/bottombar_menu&quot;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On the surface, it looks very simple and limited in customization. For example, you can selectively display item text labels if you wish, change tint color and more. To give you a hint, all this is possible using &apos;&lt;a href=&quot;https://developer.android.com/guide/topics/resources/color-list-resource.html&quot;&gt;State Selectors&lt;/a&gt;&apos;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;READ&lt;/strong&gt;&lt;br /&gt;
The &lt;a href=&quot;https://blog.iamsuleiman.com/using-bottom-navigation-view-android-design-support-library/&quot;&gt;Bottom Navigation tutorial&lt;/a&gt; for in-depth customization and more.&lt;/p&gt;
&lt;h3&gt;2. Bottom Sheet&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Bottom Sheets&lt;/strong&gt; slide up from the bottom of the screen to reveal more content.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./mega-guide-android-material-design-components/bottom-sheets-maps.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Bottom Sheet as seen on Google Maps Android app&lt;/p&gt;
&lt;p&gt;&lt;code&gt;BottomSheet&lt;/code&gt; was added to Design Support Library in v23.2.0. It also included a whole new &lt;code&gt;BottomSheetBehavior&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Simply add your Bottom Sheet directly within &lt;code&gt;CoordinatorLayout&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;androidx.coordinatorlayout.widget.CoordinatorLayout&amp;gt;
 ...
  &amp;lt;androidx.core.widget.NestedScrollView
  app:behavior_peekHeight=&quot;312dp&quot;
  app:layout_behavior=&quot;com.google.android.material.bottomsheet.BottomSheetBehavior&quot; /&amp;gt;
 ...
&amp;lt;/androidx.coordinatorlayout.widget.CoordinatorLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Additionally, you can make your Bottom Sheet react to on-scroll events. You can see such an example in the GIF above. The FAB contracts on expand, and grows (appears) on collapsing the bottom bar.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;READ&lt;/strong&gt;&lt;br /&gt;
The &lt;a href=&quot;https://blog.iamsuleiman.com/bottom-sheet-android-design-support-library/&quot;&gt;Android Bottom Sheet tutorial&lt;/a&gt; teaches you how to do all of this and more.&lt;/p&gt;
&lt;h3&gt;3. Floating Action Button (FAB)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;A floating action button represents the primary action in an application.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The most important action that users will perform on a screen, must reside in a Floating Action Button (FAB). It represents a promoted action on-screen.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./mega-guide-android-material-design-components/image03.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Material Design Floating Action Button. Image Credit: &lt;a href=&quot;https://android-developers.googleblog.com/2015/05/android-design-support-library.html&quot;&gt;Android Developers Blog&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Just like any other UI widget, you’d simply include it in your XML layout. Use the class &lt;code&gt;FloatingActionButton&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;com.google.android.material.floatingactionbutton.FloatingActionButton
   android:src=&quot;@drawable/your_icon&quot;
   app:rippleColor=&quot;@color/rippleColor&quot; 
   app:fabSize=&quot;normal&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, &lt;a href=&quot;http://Materialdoc.com&quot;&gt;Materialdoc.com&lt;/a&gt; does a fine job of covering the FAB in detail. Paresh Mayani brilliantly explains how to use, style and customize it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;READ:&lt;/strong&gt; &lt;a href=&quot;http://www.materialdoc.com/floating-action-button/&quot;&gt;Floating Action Button on &lt;em&gt;materialdoc.com&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you’re using a FAB in your apps, keep the following in mind and use it carefully.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Chose your promoted action wisely&lt;/li&gt;
&lt;li&gt;You may risk de-prioritising other onscreen actions&lt;/li&gt;
&lt;li&gt;It may block your screen, as it is an overlay&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. Floating labels (for &lt;code&gt;EditText&lt;/code&gt;)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;When the user engages with the text input field, the floating inline labels move to float above the field.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Image Credit: &lt;a href=&quot;https://material.io/develop/android/components/text-input-layout/&quot;&gt;materialdoc.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Again, implementing this is simple. Just wrap your existing &lt;code&gt;EditText&lt;/code&gt; with &lt;code&gt;TextInputLayout&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&amp;lt;com.google.android.material.textfield.TextInputLayout
android:layout_width=&quot;match_parent&quot;
android:layout_height=&quot;wrap_content&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;/com.google.android.material.textfield.TextInputLayout&amp;gt;&lt;/p&gt;
&lt;p&gt;To further style your Floating Labels, you can read &lt;a href=&quot;http://www.materialdoc.com/floating-label/&quot;&gt;Floating Labels on materialdoc.com&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;5. Material Design Tabs&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Tabs make it easy to explore and switch between different views.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./mega-guide-android-material-design-components/tabs-defined-e1433590539228.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Material Design Tabs&lt;/p&gt;
&lt;p&gt;We’re all very familiar with Tabs. But the Design Support Library introduced a new &lt;code&gt;TabLayout&lt;/code&gt; class which by default, styles your Tab in Material Design flavor.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;androidx.coordinatorlayout.widget.CoordinatorLayout&amp;gt;
    &amp;lt;com.google.android.material.appbar.AppBarLayout&amp;gt;

        &amp;lt;com.google.android.material.tabs.TabLayout
            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;wrap_content&quot; /&amp;gt;

    &amp;lt;/com.google.android.material.appbar.AppBarLayout&amp;gt;

    &amp;lt;android.support.v4.view.ViewPager
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;match_parent&quot;
        app:layout_behavior=&quot;@string/appbar_scrolling_view_behavior&quot; /&amp;gt;
&amp;lt;/androidx.coordinatorlayout.widget.CoordinatorLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;READ&lt;/strong&gt;&lt;br /&gt;
How to create &lt;a href=&quot;https://blog.iamsuleiman.com/material-design-tabs-with-android-design-support-library/&quot;&gt;Material Design Tabs with Android Design Support Library&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;6. Navigation Drawer&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;The navigation drawer slides in from the left and contains the navigation destinations for your app.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In the early days, making a Navigation Drawer in Android took considerable effort. With Material Design things got even harder.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./mega-guide-android-material-design-components/navigation-drawer-then-and-now-744x418.png&quot; alt=&quot;navigation drawer google+ material design&quot; /&gt;&lt;/p&gt;
&lt;p&gt;However, adding a Navigation Drawer now is a breeze. All your drawer items are loaded from a menu resource. The drawer header is a separate layout.xml. Honestly, it can’t get any easier than this.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;androidx.drawerlayout.widget.DrawerLayout
    xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    android:fitsSystemWindows=&quot;true&quot;&amp;gt;

    &amp;lt;!-- your content layout --&amp;gt;

    &amp;lt;com.google.android.material.navigation.NavigationView
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;match_parent&quot;
        android:layout_gravity=&quot;start&quot;
        android:fitsSystemWindows=&quot;true&quot;
        app:headerLayout=&quot;@layout/drawer_header&quot;
        app:menu=&quot;@menu/drawer&quot; /&amp;gt;

&amp;lt;/androidx.drawerlayout.widget.DrawerLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;READ&lt;/strong&gt;&lt;br /&gt;
&lt;a href=&quot;https://blog.iamsuleiman.com/easy-navigation-drawer-with-design-support-library/&quot;&gt;Navigation Drawer with Design Support Library - Android Tutorial&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;7. Snackbar&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;A lightweight component that gives feedback to users. It optionally provides an action to users.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./mega-guide-android-material-design-components/snackbar.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Here&apos;s a simple &lt;code&gt;Snackbar&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Snackbar&lt;br /&gt;
.make(view, &quot;Your message here&quot;,&lt;br /&gt;
Snackbar.LENGTH_SHORT)
.show();&lt;/p&gt;
&lt;p&gt;Note that &quot;view&quot; can be any &lt;code&gt;View&lt;/code&gt; from your layout.&lt;/p&gt;
&lt;p&gt;I know, you might say that if you remove the action, it&apos;s a &lt;code&gt;Toast&lt;/code&gt;. I agree with you. But in one line, here&apos;s the difference.&lt;/p&gt;
&lt;p&gt;Toasts are usually for important system related messages.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;READ&lt;/strong&gt;&lt;br /&gt;
&lt;a href=&quot;https://blog.iamsuleiman.com/material-design-snackbar&quot;&gt;How and when to use a Snackbar correctly&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Animations&lt;/h2&gt;
&lt;h3&gt;&lt;strong&gt;1. Quick Return&lt;/strong&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;The Toolbar scrolls off-screen with the rest of the scrollable content, but upon scrolling slightly up at any point, it scrolls back into view.&lt;/p&gt;
&lt;p&gt;– Quick Return Animation Pattern&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Quick Return is a useful pattern that provides more vertical space for your content.&lt;/p&gt;
&lt;p&gt;They key to enabling this animation is as simple as adding this flag to your &lt;code&gt;Toolbar&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;app:layout_scrollFlags=&quot;scroll|enterAlways&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/mega-guide-android-material-design-components/quick-return_opt.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;It is also possible to combine Quick Return with the Flexible Space pattern. Simply add this flag to get it working!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;READ&lt;/strong&gt;&lt;br /&gt;
Learn via a more detailed demonstration in the &lt;a href=&quot;https://blog.iamsuleiman.com/quick-return-pattern-with-android-design-support-library/&quot;&gt;Android Quick Return tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;2. Flexible Space with Image&lt;/strong&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;A scrolling technique that supports an image header with a scrollable view below it. Upon scrolling, the ‘Flexible Space’ (image header) fades into a color. At the same time, it collapses into a Toolbar.&lt;/p&gt;
&lt;p&gt;–- &lt;a href=&quot;https://material.io/guidelines/patterns/scrolling-techniques.html#scrolling-techniques-scrolling&quot;&gt;Material Design guidelines&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now it&apos;s obviously clear when you would want to use this pattern. It works best when you have a header image. You&apos;ll understand the Flexible Space pattern better via a GIF.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/mega-guide-android-material-design-components/flexible_space_toolbar_menu.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Note that in this GIF, the Toolbar doesn&apos;t always have to tint with the primary brand color. It also can take on the image&apos;s dominant color. You can fetch an image&apos;s dominant color, including a variety of other colors using the Palette API.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;READ&lt;/strong&gt;&lt;br /&gt;
&lt;a href=&quot;https://blog.iamsuleiman.com/toolbar-animation-with-android-design-support-library/&quot;&gt;How to create a collapsing toolbar animation, including Palette API&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;3. Parallax Scrolling (header)&lt;/strong&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Parallax scrolling is where one element scrolls at a different speed compared to other elements.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In our case, we&apos;ll apply parallax scrolling to &lt;code&gt;ImageView&lt;/code&gt;.  So our ImageView will scroll at a different rate compared to CollapsingToolbar.&lt;/p&gt;
&lt;p&gt;For a bit, head back to our Flexible Space pattern animation. Remember that I said it predominantly uses an ImageView for its header?&lt;/p&gt;
&lt;p&gt;You just need one attribute to enable parallax scrolling on the &lt;code&gt;ImageView&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;app:layout_collapseMode=&quot;parallax&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you want the parallax effect to be more profound, add a multiplier.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;app:layout_collapseParallaxMultiplier=&quot;0.5&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h3&gt;ProGuard rules for Design Support Library&lt;/h3&gt;
&lt;p&gt;Lastly, don’t forget to add ProGuard rules. I’m sure the apps you build will go on to be production-ready. You’ll even upload it on the Play Store.&lt;/p&gt;
&lt;p&gt;So when you’re generating your release build. Add these lines to your &lt;em&gt;app/proguard-rules.pro&lt;/em&gt; file.&lt;/p&gt;
&lt;p&gt;-dontwarn android.support.design.**
-keep class android.support.design.** { *; }
-keep interface android.support.design.** { *; }
-keep public class android.support.design.R$* { *; }&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;
If you’re using a lot of libraries, adding ProGuard rules can be hard. So here’s a &lt;a href=&quot;https://github.com/krschultz/android-proguard-snippets&quot;&gt;useful collection of ProGuard snippets&lt;/a&gt; that will help you.&lt;/p&gt;
&lt;h2&gt;Key Takeaways&lt;/h2&gt;
&lt;p&gt;Being a user of Design Support library since its advent, I say this from experience. If you plan on building a Material Design Android app, this library is a must-have.&lt;/p&gt;
&lt;p&gt;I hope this list was exhaustive and convincing enough for you. It&apos;s about time you made the jump to the Design Support Library.&lt;/p&gt;
&lt;p&gt;Stop using external libraries that do the same thing. I’m not saying that they’re bad in any way. But I&apos;d prefer using official implementation and reduce third-party dependency when possible.&lt;/p&gt;
&lt;p&gt;How will you use Material Components in your Android app? Let me know in the comments below.&lt;/p&gt;
</content:encoded></item><item><title>Android Architecture Components Tutorial - Room, LiveData and ViewModel</title><link>https://blog.iamsuleiman.com/android-architecture-components-tutorial-room-livedata-viewmodel/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/android-architecture-components-tutorial-room-livedata-viewmodel/</guid><description>During the concluded Google I/O 2017, there were some amazing announcements about Android. Say hello to Android Architecture Components. For once, the</description><pubDate>Tue, 23 May 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;During the concluded Google I/O 2017, there were some amazing announcements about Android. Say hello to &lt;strong&gt;Android Architecture Components&lt;/strong&gt;. For once, these are announcements that ease our lives as Android Developers.&lt;/p&gt;
&lt;h2&gt;Android Architecture Components&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A new collection of libraries that help you design robust, testable, and maintainable apps. - &lt;a href=&quot;http://developer.android.com&quot;&gt;developer.android.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It helps us developers address two pain points:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Manage our UI components lifecycle&lt;/li&gt;
&lt;li&gt;Persist data over configuration changes&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In fact, these are the two biggest problems we Android Developers face. Period. Maintaining data over orientation changes and handling our objects with lifecycle is hard. That’s why, to avoid the hassle, you lock your apps in Portrait mode, don’t you? Don’t lie. Even I’ve done it. But don’t worry, Android Architecture Components will help alleviate both our fears. There are 3 main architecture components:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Room&lt;/li&gt;
&lt;li&gt;LiveData&lt;/li&gt;
&lt;li&gt;ViewModel&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So first, let&apos;s find out what these components actually are. Then, we’ll learn how we can use them. We’ll even make a handy app that keeps track of what people borrow. This will help us learn better about how all these 3 components work together.&lt;/p&gt;
&lt;h3&gt;Room&lt;/h3&gt;
&lt;p&gt;Remember the amount of boilerplate code you had to write to create and manipulate even a very small database? You had to define the database structure, create an &lt;strong&gt;SQLiteHelper&lt;/strong&gt; class etc. Room is a library that saves you all such trouble. Now you can query your data without having to deal with cursors or loaders. You can define your database by adding annotations in your Model class. Yes, it&apos;s that simple. If you’ve used third-party ORMs like &lt;a href=&quot;http://satyan.github.io/sugar/&quot;&gt;Sugar&lt;/a&gt;, you’ll feel right at home here. In fact, from now on, I wouldn’t even want to use one. Room is that brilliant! Why would you want to use a third-party library, when the official Android libraries give you an equal, or if not, better solution.&lt;/p&gt;
&lt;h4&gt;Architecture&lt;/h4&gt;
&lt;p&gt;In this app, we will follow an architecture called &lt;strong&gt;MVVM - Model View ViewModel&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In MVVM, the &lt;code&gt;ViewModel&lt;/code&gt; exposes the required data and interested parties can listen to it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But you don&apos;t have to worry. We&apos;ll do a simple implementation for this article. You&apos;ll have no problem following. So in our case, the &lt;code&gt;Activity&lt;/code&gt; will listen on the data and make changes in the UI.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Getting started&lt;/h2&gt;
&lt;p&gt;Create a new project in Android Studio. First, Add Google&apos;s maven repository to your &lt;strong&gt;project-level&lt;/strong&gt; &lt;em&gt;build.gradle&lt;/em&gt; file.&lt;/p&gt;
&lt;p&gt;//...
allprojects {
repositories {
jcenter()
maven {
url &quot;&lt;a href=&quot;https://maven.google.com&quot;&gt;https://maven.google.com&lt;/a&gt;&quot;
}
}
}
//...&lt;/p&gt;
&lt;p&gt;Next, add the following dependencies for Room in your &lt;strong&gt;app-level&lt;/strong&gt; &lt;em&gt;build.gradle&lt;/em&gt; file.&lt;/p&gt;
&lt;p&gt;compile &quot;android.arch.lifecycle:extensions:1.0.0&quot;
compile &quot;android.arch.persistence.room:runtime:1.0.0&quot;
annotationProcessor &quot;android.arch.lifecycle:compiler:1.0.0&quot;
annotationProcessor &quot;android.arch.persistence.room:compiler:1.0.0&quot;&lt;/p&gt;
&lt;h3&gt;Creating the Model&lt;/h3&gt;
&lt;p&gt;Create a class called &lt;em&gt;BorrowModel&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;import java.util.Date;
@Entity
public class BorrowModel {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@PrimaryKey(autoGenerate = true)
public int id;
private String itemName;
private String personName;
@TypeConverters(DateConverter.class)
private Date borrowDate;

public BorrowModel(String itemName, String personName, Date borrowDate) {
    this.itemName = itemName;
    this.personName = personName;
    this.borrowDate = borrowDate;
}

public String getItemName() {
    return itemName;
}

public String getPersonName() {
    return personName;
}

public Date getBorrowDate() {
    return borrowDate;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;You might see an error at &lt;em&gt;DateConverter.class&lt;/em&gt;. But don&apos;t panic, we&apos;ll create that next. So for now, pay attention to the Annotations used here. We use the &lt;strong&gt;&lt;code&gt;@Entity&lt;/code&gt;&lt;/strong&gt; annotation to tell Room to use the current class as a database table. Any attribute preceded by the &lt;code&gt;@PrimaryKey&lt;/code&gt; annotation will serve as a primary key for the table. Here we use &lt;code&gt;&apos;autoGenerate = true&apos;&lt;/code&gt; so that the key is automatically generated every time an entry is made. SQL cannot store data types like &lt;code&gt;Date&lt;/code&gt; by default. That&apos;s why we need a way to convert it into a compatible data type to store it in the database. We use the &lt;code&gt;@TypeConverters&lt;/code&gt; to specify the converter for the &lt;code&gt;borrowDate&lt;/code&gt; attribute. So to help us with this conversion, we&apos;ll create a class called &lt;em&gt;DateConverter&lt;/em&gt;. &lt;strong&gt;NOTE:&lt;/strong&gt; Make sure to import &lt;code&gt;java.util.Date;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;import java.util.Date;
class DateConverter {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@TypeConverter
public static Date toDate(Long timestamp) {
    return timestamp == null ? null : new Date(timestamp);
}

@TypeConverter
public static Long toTimestamp(Date date) {
    return date == null ? null : date.getTime();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;As you can see, the class just converts &lt;code&gt;Date&lt;/code&gt; to &lt;code&gt;Long&lt;/code&gt; and vice versa.&lt;/p&gt;
&lt;h4&gt;Data Access Object&lt;/h4&gt;
&lt;p&gt;Next up, we need to create a DAO - Data Access Object class. This class will be used to define all the queries we will perform on our database.&lt;/p&gt;
&lt;p&gt;@Dao
@TypeConverters(DateConverter.class)
public interface BorrowModelDao {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Query(&quot;select \* from BorrowModel&quot;)
LiveData&amp;lt;List&amp;lt;BorrowModel&amp;gt;&amp;gt; getAllBorrowedItems();

@Query(&quot;select \* from BorrowModel where id = :id&quot;)
BorrowModel getItembyId(String id);

@Insert(onConflict = REPLACE)
void addBorrow(BorrowModel borrowModel);

@Delete
void deleteBorrow(BorrowModel borrowModel);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;We use &lt;code&gt;@Dao&lt;/code&gt; to tell Room that this is a DAO class. We define our queries as strings and pass them as a parameter to &lt;code&gt;@Query&lt;/code&gt;. Each &lt;code&gt;@Query&lt;/code&gt; annotation is paired with a method. When the paired method is called, the query gets executed. Next, we use the &lt;code&gt;@Insert&lt;/code&gt; annotation for methods that insert entries into the table. We can similarly use &lt;code&gt;@Delete&lt;/code&gt; and &lt;code&gt;@Update&lt;/code&gt; for deletion and update methods respectively. In case there are conflicts during such manipulation operations, we have to specify a conflict strategy too. In our example, we are using &lt;strong&gt;REPLACE&lt;/strong&gt;. It means that the conflicting entry will be replaced by the current entry. Make sure you import REPLACE correctly using &lt;code&gt;import static android.arch.persistence.room.OnConflictStrategy.REPLACE;&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;Creating the database&lt;/h4&gt;
&lt;p&gt;Now, all we need to do is create a &lt;em&gt;RoomDatabase&lt;/em&gt; class. So create an &lt;strong&gt;abstract&lt;/strong&gt; class called &lt;em&gt;AppDatabase&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;@Database(entities = {BorrowModel.class}, version = 1)
public abstract class AppDatabase extends &lt;strong&gt;RoomDatabase&lt;/strong&gt; {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static AppDatabase INSTANCE;

public static AppDatabase getDatabase(Context context) {
    if (INSTANCE == null) {
        INSTANCE =
                Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, &quot;borrow_db&quot;)
                        .build();
    }
    return INSTANCE;
}

public abstract BorrowModelDao itemAndPersonModel();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;We annotate the class with &lt;code&gt;@Database&lt;/code&gt; which takes two arguments:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;An array of the Entity classes(the tables)&lt;/li&gt;
&lt;li&gt;The database version which is just an integer.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This class is used to create the database and get an instance of it. We create the database using&lt;/p&gt;
&lt;p&gt;Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, &quot;borrow_db&quot;)
.build();&lt;/p&gt;
&lt;p&gt;The arguments are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Context&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Your database class&lt;/li&gt;
&lt;li&gt;Name to given to the database&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;TIP:&lt;/strong&gt; We have to create an abstract method for every DAO class that we create. This is really important. And that&apos;s it. Our database is ready to roll.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;ViewModel&lt;/h2&gt;
&lt;p&gt;Earlier in the post, we mentioned &lt;code&gt;ViewModel&lt;/code&gt;. ViewModels are entities that are free of the &lt;code&gt;Activity&lt;/code&gt;/&lt;code&gt;Fragment&lt;/code&gt; lifecycle. For example, they can retain their state/data even during an orientation change. ViewModels do not contain code related to the UI. This helps in the decoupling of our app components. In &lt;code&gt;Room&lt;/code&gt;, the database instance should ideally be contained in a ViewModel rather than on the &lt;code&gt;Activity&lt;/code&gt;/&lt;code&gt;Fragment&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Create the AndroidViewModel&lt;/h3&gt;
&lt;p&gt;We create a ViewModel for our borrowed items.&lt;/p&gt;
&lt;p&gt;public class BorrowedListViewModel extends AndroidViewModel {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private final LiveData&amp;lt;List&amp;lt;BorrowModel&amp;gt;&amp;gt; itemAndPersonList;

private AppDatabase appDatabase;

public BorrowedListViewModel(Application application) {
    super(application);

    appDatabase = AppDatabase.getDatabase(this.getApplication());

    itemAndPersonList = appDatabase.itemAndPersonModel().getAllBorrowedItems();
}

public LiveData&amp;lt;List&amp;lt;BorrowModel&amp;gt;&amp;gt; getItemAndPersonList() {
    return itemAndPersonList;
}

public void deleteItem(BorrowModel borrowModel) {
    new deleteAsyncTask(appDatabase).execute(borrowModel);
}

private static class deleteAsyncTask extends AsyncTask&amp;lt;BorrowModel, Void, Void&amp;gt; {

    private AppDatabase db;

    deleteAsyncTask(AppDatabase appDatabase) {
        db = appDatabase;
    }

    @Override
    protected Void doInBackground(final BorrowModel... params) {
        db.itemAndPersonModel().deleteBorrow(params\[0\]);
        return null;
    }

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Every ViewModel class must extend the &lt;code&gt;ViewModel&lt;/code&gt; class. If  the ViewModel needs the application context, then it must extend the &lt;code&gt;AndroidViewModel&lt;/code&gt; class. The ViewModel will contain all the data needed for our &lt;code&gt;Activity&lt;/code&gt;. In our example, we are using something called &lt;strong&gt;LiveData&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;LiveData is a wrapper that lets interested classes observe changes in the data inside the wrapper.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We wrap our list of borrowed items inside LiveData so that the &lt;code&gt;Activity&lt;/code&gt; can observe changes in the data and update the UI. In our ViewModel, we first get an instance of our database using &lt;code&gt;AppDatabase.getDatabase(this.getApplication())&lt;/code&gt; First, we need to load the list of borrowed items from the database. For that, we should use the query we defined in the DAO class, &lt;code&gt;getAllBorrowedItems()&lt;/code&gt;. Next, call the abstract method we created for DAO and then call the query method. Refer to this snippet in the &lt;code&gt;BorrowedListViewModel&lt;/code&gt; class.&lt;/p&gt;
&lt;p&gt;appDatabase.itemAndPersonModel().getAllBorrowedItems();&lt;/p&gt;
&lt;p&gt;Now since we will be displaying a list of items, we need a &lt;code&gt;RecyclerView&lt;/code&gt;. So first, let&apos;s create an adapter for the same.&lt;/p&gt;
&lt;p&gt;public class RecyclerViewAdapter extends RecyclerView.Adapter&amp;lt;RecyclerViewAdapter.RecyclerViewHolder&amp;gt; {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private List&amp;lt;BorrowModel&amp;gt; borrowModelList;
private View.OnLongClickListener longClickListener;

public RecyclerViewAdapter(List&amp;lt;BorrowModel&amp;gt; borrowModelList, View.OnLongClickListener longClickListener) {
    this.borrowModelList = borrowModelList;
    this.longClickListener = longClickListener;
}

@Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    return new RecyclerViewHolder(LayoutInflater.from(parent.getContext())
            .inflate(R.layout.recycler_item, parent, false));
}

@Override
public void onBindViewHolder(final RecyclerViewHolder holder, int position) {
    BorrowModel borrowModel = borrowModelList.get(position);
    holder.itemTextView.setText(borrowModel.getItemName());
    holder.nameTextView.setText(borrowModel.getPersonName());
    holder.dateTextView.setText(borrowModel.getBorrowDate().toLocaleString().substring(0, 11));
    holder.itemView.setTag(borrowModel);
    holder.itemView.setOnLongClickListener(longClickListener);
}

@Override
public int getItemCount() {
    return borrowModelList.size();
}

public void addItems(List&amp;lt;BorrowModel&amp;gt; borrowModelList) {
    this.borrowModelList = borrowModelList;
    notifyDataSetChanged();
}

static class RecyclerViewHolder extends RecyclerView.ViewHolder {
    private TextView itemTextView;
    private TextView nameTextView;
    private TextView dateTextView;

    RecyclerViewHolder(View view) {
        super(view);
        itemTextView = (TextView) view.findViewById(R.id.itemTextView);
        nameTextView = (TextView) view.findViewById(R.id.nameTextView);
        dateTextView = (TextView) view.findViewById(R.id.dateTextView);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h4&gt;Creating the Android LifecycleActivity&lt;/h4&gt;
&lt;p&gt;It&apos;s a pretty straightforward adapter. So I won&apos;t be getting into the details of it. But if you&apos;re interested in how &lt;code&gt;RecyclerView&lt;/code&gt; works, this &lt;a href=&quot;https://blog.iamsuleiman.com/pinterest-masonry-layout-staggered-grid/&quot;&gt;Android tutorial tells you how to create a &lt;code&gt;RecyclerView.Adapter&lt;/code&gt;&lt;/a&gt;. Now create an &lt;code&gt;Activity&lt;/code&gt; that extends &lt;strong&gt;&lt;code&gt;LifecycleActivity&lt;/code&gt;&lt;/strong&gt; to display a list of all the borrowed items.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;LifecycleActivity&lt;/code&gt; is a class that provides us with the state of the lifecycle.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;public class MainActivity extends &lt;strong&gt;LifecycleActivity&lt;/strong&gt; implements View.OnLongClickListener {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private BorrowedListViewModel viewModel;
private RecyclerViewAdapter recyclerViewAdapter;
private RecyclerView recyclerView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            startActivity(new Intent(MainActivity.this, AddActivity.class));
        }
    });

    recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
    recyclerViewAdapter = new RecyclerViewAdapter(new ArrayList&amp;lt;BorrowModel&amp;gt;(), this);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));

    recyclerView.setAdapter(recyclerViewAdapter);

    viewModel = ViewModelProviders.of(this).get(BorrowedListViewModel.class);

    viewModel.getItemAndPersonList().observe(MainActivity.this, new Observer&amp;lt;List&amp;lt;BorrowModel&amp;gt;&amp;gt;() {
        @Override
        public void onChanged(@Nullable List&amp;lt;BorrowModel&amp;gt; itemAndPeople) {
            recyclerViewAdapter.addItems(itemAndPeople);
        }
    });

}

@Override
public boolean onLongClick(View v) {
    BorrowModel borrowModel = (BorrowModel) v.getTag();
    viewModel.deleteItem(borrowModel);
    return true;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Whenever we need to use ViewModels inside our &lt;code&gt;Activity&lt;/code&gt;, the &lt;code&gt;Activity&lt;/code&gt; must extend &lt;code&gt;LifecycleActivity&lt;/code&gt;. Creating a ViewModel is simple.&lt;/p&gt;
&lt;p&gt;viewModel = ViewModelProviders.of(this).get(BorrowedListViewModel.class);&lt;/p&gt;
&lt;p&gt;The two parameters are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Context&lt;/li&gt;
&lt;li&gt;The ViewModel class&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now we need to make our &lt;code&gt;Activity&lt;/code&gt; observe the changes in the ViewModel. So first, get a reference to the LiveData inside the ViewModel. Then, add an &lt;code&gt;observe()&lt;/code&gt; method to the reference. The &lt;code&gt;observe()&lt;/code&gt; method takes 2 parameters:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The owner of the Lifecycle. In our case, it is the &lt;code&gt;Activity&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;An &lt;a href=&quot;http://www.vogella.com/tutorials/DesignPatternObserver/article.html&quot;&gt;&lt;code&gt;Observer&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Whenever there is a change in the data, the &lt;code&gt;onChanged()&lt;/code&gt; callback is executed and we get the new data. We can update the UI accordingly.&lt;/p&gt;
&lt;h5&gt;Simple Exercise - Create the &apos;Add Item Screen&apos;&lt;/h5&gt;
&lt;p&gt;Now we have an &lt;code&gt;Activity&lt;/code&gt; that can display a list of borrowed items. But how do we add items to the database? It&apos;s simple. You need to create an &lt;em&gt;AddItemActivity&lt;/em&gt;. The entire procedure is exactly the same as before. But in this case, you need to call the &lt;code&gt;addBorrow()&lt;/code&gt; DAO method and pass a &lt;code&gt;Borrow&lt;/code&gt; object as a parameter. And that is it. Our app is ready. I encourage you to try this screen on your own. But in case you get stuck, you can &lt;a href=&quot;https://github.com/SubhrajyotiSen/Borrow/tree/master/app/src/main/java/com/subhrajyoti/borrow/addItem&quot;&gt;refer to my files on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Output&lt;/h2&gt;
&lt;p&gt;So go ahead and run your app. You should get an output similar to this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/android-architecture-components-tutorial-room-livedata-viewmodel/room_demo.gif&quot; alt=&quot;Room demo GIF&quot; title=&quot;Room demo GIF&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The Android Architecture Components give us great advantage and relief. Hence, we don&apos;t have to worry about&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;lifecycle changes&lt;/li&gt;
&lt;li&gt;memory leaks&lt;/li&gt;
&lt;li&gt;data retention across configuration changes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you recount, these are the biggest challenges faced by even veteran Android developers. &lt;strong&gt;Source Code:&lt;/strong&gt; As always, the code from the post can be found on &lt;a href=&quot;http://github.com/SubhrajyotiSen/Borrow&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Wrap up&lt;/h2&gt;
&lt;p&gt;In the post, we got introduced to Android Architecture Components. Then, we learnt about Room and used it to create databases in a fast and easy way. Next, we also learnt how to make our UI respond to changes in data. Also, by using &lt;code&gt;LiveData&lt;/code&gt; and &lt;code&gt;ViewModels&lt;/code&gt;, we did not have to use a lot of callbacks. Additionally, we even learnt a bit about the MVVM architecture. We have barely scratched the surface in terms of what&apos;s possible with these new components. So I hope to discover more as I continue to tinker with Android Architecture Components. So are you going to use these components? Would you consider &lt;code&gt;Room&lt;/code&gt; in any of your apps? Or maybe ViewModels to simplify your code? I&apos;d love to hear your comments.&lt;/p&gt;
</content:encoded></item><item><title>Horizontal Scrolling Lists in Mobile - Best Practices</title><link>https://blog.iamsuleiman.com/horizontal-scrolling-lists-mobile-best-practices/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/horizontal-scrolling-lists-mobile-best-practices/</guid><description>Many Android and iOS apps have horizontal scrolling lists. Maybe it’s also combined inside a vertical list. But is it necessary? Even assuming it is, </description><pubDate>Tue, 09 May 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Many Android and iOS apps have horizontal scrolling lists. Maybe it’s also combined inside a vertical list. But is it necessary? Even assuming it is, are you doing it right?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Horizontal lists are better-suited for mobile, as gestures are both horizontal and vertical.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./horizontal-scrolling-lists-mobile-best-practices/screen696x696.jpeg&quot; alt=&quot;&quot; title=&quot;Netflix iOS app&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Yet, people including you and me both, mostly vertical scrolling. I mean seriously, what’s the first natural thing you do, when you open an app? You scroll. Vertically. Okay, maybe you check your notifications, but even there, you scroll. Vertically. So how do you tell people that they can horizontal scroll too? Or rather, when should we use horizontal scrolling?&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;When to use Horizontal Lists&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Horizontal lists work best when you want to display a subset of homogeneous content that’s part of a heterogeneous set.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Makes sense? Take the Play Store app for Android. Sure the Play Store is all about finding new apps. But for us to search better, apps need to be categorized right? For example, you can subcategorize apps into games, utility and social, to name a few. Hence each category of apps, can be in a horizontal list.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./horizontal-scrolling-lists-mobile-best-practices/play-store.png&quot; alt=&quot;&quot; title=&quot;Google Play Store app on Android&quot; /&gt;&lt;/p&gt;
&lt;p&gt;As you can see, Play Store gives us an assortment of apps. There&apos;s a bunch of &apos;Recommended&apos; apps you can browse (horizontally). Then, there&apos;s a set of apps that are &apos;New+Updated&apos;. So to go by the definition above, each subcategory of apps are in a horizontal list. These child lists are put into a (parent) vertical list. You can scroll vertically to find more such subcategories. Here’s another example.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./horizontal-scrolling-lists-mobile-best-practices/amazon_prime_video_android.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Amazon Prime Video — Android App. Image Credits: &lt;a href=&quot;https://medium.com/r/?url=http%3A%2F%2Fwww.pcadvisor.co.uk%2Fhow-to%2Fphoto-video%2Fhow-watch-amazon-prime-on-android-3637285%2F&quot;&gt;pcadvisor.co.uk&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Design Tips for Horizontal lists on Mobile&lt;/h3&gt;
&lt;p&gt;In the web, arrows show that there is a horizontal list of content you can scroll. This is typically a carousel. It uses a combination of arrows for navigation, dots for indication and scrollbars. These are indicators (affordances) that tell people how to navigate a carousel.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./horizontal-scrolling-lists-mobile-best-practices/flipkart-website-carousel.png&quot; alt=&quot;&quot; title=&quot;Carousel seen on Flipkart website&quot; /&gt;&lt;/p&gt;
&lt;p&gt;But how would you design horizontal lists on mobile? Mobile apps are touch based and support gestures. Would you still be using point and click mechanisms such as arrows? I’m sure not. Moreover, given mobile size constraints, using the same web paradigms makes little sense. Hence there must be a better way. Expect users to scroll the same way they would in a vertical list. Here are some design tips to keep in mind. They can help you make better and effective horizontal lists.&lt;/p&gt;
&lt;h4&gt;Show Visual Indicators&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;The design must leave a visual hint that a set of content is horizontally scrollable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Assume you’re displaying a horizontal list of cards. You’d want the last card on the right, to &lt;strong&gt;peek out&lt;/strong&gt; from the edge.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./horizontal-scrolling-lists-mobile-best-practices/horizontal-lists-peek.png&quot; alt=&quot;&quot; title=&quot;Horizontal Lists with the last visible item &apos;peeking&apos; from the edge&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So for this particular device width, we can show two cards. To see the third card and beyond, we need to scroll horizontally. Notice the design teases a bit of the third card. Yes, the pink cards at the extreme ends that are partially hidden. This ‘tease’ provides a subtle hint that there’s more content. Since the flow of content is horizontal, it naturally indicates users in which direction to scroll. Hence, the user’s natural instinct is to scroll in that direction (horizontally).&lt;/p&gt;
&lt;h4&gt;Use a &apos;See More&apos; Button&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;See More, See All, View All, View More, Show More ...&lt;/em&gt; Call the button what you want. Essentially, it should mean one thing:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A &apos;See More&apos; button tells users there&apos;s more of where that came from. It&apos;s hints that there&apos;s more of similar content available.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Keep in mind, that each subcategory (horizontal list), is just a tease of what kind of content you can expect.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./horizontal-scrolling-lists-mobile-best-practices/horizontal-lists-see-more.png&quot; alt=&quot;&quot; title=&quot;Using a vertical, 3-column grid in &apos;See All&apos; screen&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So when a user taps on &quot;See More&quot;, you want to show them all that&apos;s there to show for that subcategory. For example, assume the user clicks the subcategory called &quot;Top Action Games&quot; in the Play Store app. Then the &apos;See  All&apos; screens shows all the best action games in that subcategory. Remember that vertical scrolling is the most natural and fastest.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Vertical scrolling increases the user&apos;s ability to skim through content&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hence, it makes sense to use a vertical grid in the See All screen.&lt;/p&gt;
&lt;h4&gt;Design for Responsiveness&lt;/h4&gt;
&lt;p&gt;Keep in mind that mobile app interfaces are responsive. So make sure that this subtle hint is always present. Otherwise, you might see a horizontal list that looks like a grid.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./horizontal-scrolling-lists-mobile-best-practices/horizontal-lists-grid.png&quot; alt=&quot;&quot; title=&quot;Horizontal lists that look like a grid&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So tell me. From the UI above, can you tell that each subcategory is a horizontal list? Moreover, can you even tell if it&apos;s horizontally scrollable? I&apos;m sure not. But you&apos;re not to blame. It&apos;s the design&apos;s fault. There is NO visual indication! Trust me, that’s not what you want people seeing. It looks just like a vertical grid. If it looks like that, then every user’s natural instinct is to scroll vertically.&lt;/p&gt;
&lt;h5&gt;Adapting Horizontal lists for Tablets&lt;/h5&gt;
&lt;p&gt;So how do you design horizontal scrolling lists on larger devices? Say tablets for example? You can convert your horizontal list into a grid with N items per row. The above UI design displays five items per row. With a see all button that indicates that a user can see more of this kind of content, on a new screen.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./horizontal-scrolling-lists-mobile-best-practices/horizontal-list-tablet.png&quot; alt=&quot;&quot; title=&quot;Horizontal Lists as a grid on Tablet&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Hence, on mobile, it can be a scrollable horizontal list of say, ten cards. However on Tablets, you could have five or six, non-scrollable cards. &lt;strong&gt;Read:&lt;/strong&gt; &lt;a href=&quot;https://blog.iamsuleiman.com/material-design-for-tablets/&quot;&gt;Getting Started with Material Design for Tablets&lt;/a&gt; - Android&lt;/p&gt;
&lt;h6&gt;Limit horizontal content on tablets&lt;/h6&gt;
&lt;p&gt;Tablets grant larger screen width. So it&apos;s wise to take advantage of large screen real-estate. But let&apos;s focus on just horizontal scrolling for a moment. It&apos;s perfectly fine on mobile. You show 3 contents by default. The rest is can be viewed by scrolling horizontally. This means that the additional content which is hidden, is optional. If users are interested, they can scroll to see more. Or if they&apos;re interested in seeing all of it, they can tap the &apos;See More&apos; button. Now let&apos;s get back to Tablets. Your natural instinct would be to simply show more content horizontally. It totally makes sense to do so right? When large width is available, it&apos;s natural to make use of it. Right? No. Let me tell you why.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./horizontal-scrolling-lists-mobile-best-practices/horizontal-list-tablet-long.png&quot; alt=&quot;&quot; title=&quot;Don&apos;t stretch horizontal lists on Tablets&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Giving a &apos;tease&apos; of five to six contents is more than enough to tell people what to expect from a category. Remember that the user may scroll horizontally to see more.  But they definitely will scroll vertically.  Moreover, if they want to see everything a category has to offer, they can tap the See All button. Hence, it makes sense to just show a non-scrollable grid of 5-6 items per subcategory. Giving too many choices is a sign of increased cognitive load for users. That&apos;s not a good thing.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Every time you visit a website, a process of learning is initiated. Your brain has to learn how to use the site while keeping track of the reason you came there in the first place. The mental effort required during this time is called &lt;strong&gt;cognitive load&lt;/strong&gt;. - &lt;a href=&quot;https://jonyablonski.com/2015/design-principles-for-reducing-cognitive-load/&quot;&gt;Design Principles for Reducing Cognitive Load&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Alright, that may be in the context of a website. But it all the more holds true on mobile. Attention span on mobile is shorter than you think and &lt;a href=&quot;http://www.telegraph.co.uk/science/2016/03/12/humans-have-shorter-attention-span-than-goldfish-thanks-to-smart/&quot;&gt;an article by The Telegraph&lt;/a&gt; agrees too!&lt;/p&gt;
&lt;h4&gt;Snap Horizontal Scrolling&lt;/h4&gt;
&lt;p&gt;This is a technique that prevents freeform scrolling. Although not entirely. Here&apos;s a GIF that will explain it better.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/horizontal-scrolling-lists-mobile-best-practices/snap_scroll.gif&quot; alt=&quot;&quot; title=&quot;Snap scrolling in horizontal list&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Here, can you see horizontal scrolling is snapped? Whenever the user scrolls horizontally, the next item becomes slightly visible. This is a subtle hint that even after scrolling, there&apos;s more content available. Although this is hardly noticeable, its a great tip to keep in mind. It&apos;s a very subtle, yet powerful hint that indicates whether there is more content or not.&lt;/p&gt;
&lt;h4&gt;Indicate the starting and ending of a list&lt;/h4&gt;
&lt;p&gt;Agreed that when the scrolling stops, we know we’ve reached the end of the list. But unless we scroll, we don’t know right? Android uses a neat animation to denote the end of a list. But that’s only when the user scrolls. Which means the user finds out AFTER they have scrolled.  Image Credits: &lt;a href=&quot;http://stackoverflow.com/questions/35148954/react-native-android-how-to-change-the-color-of-listview-end-of-scroll-animat&quot;&gt;Stack Overflow&lt;/a&gt; Would you expect your users to scroll to find out? Wouldn’t it be better if you could visually indicate that too? Use extra spacing to denote the end of a list. This is the extreme left and right.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./horizontal-scrolling-lists-mobile-best-practices/horizontal-lists-spacing.png&quot; alt=&quot;&quot; title=&quot;Extra spacing at the extreme end of horizontal lists&quot; /&gt;&lt;/p&gt;
&lt;h5&gt;Indicate Vertical Scrolling too&lt;/h5&gt;
&lt;p&gt;Assume your app supports both horizontal and vertical scrolling. We’ve already discussed leaving visual hints indicating horizontal scrolling. How do you indicate vertical scroll? Websites indicate a vertical scrollbar on the side. But what about mobile? Here’s a neat trick you can use, although not seen in many apps. Use a light faded scrim at the bottom.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./horizontal-scrolling-lists-mobile-best-practices/horizontal-lists-vertical-scrim.png&quot; alt=&quot;&quot; title=&quot;Vertical scrim at the bottom that hints there&apos;s more content&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;Don’t confuse Tabs with Horizontal Lists&lt;/h4&gt;
&lt;p&gt;Let me put this one bluntly. Assume your app has Tabs and one of them includes a horizontally scrolling list. Say, something like this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./horizontal-scrolling-lists-mobile-best-practices/horizontal-lists-with-tabs.png&quot; alt=&quot;&quot; title=&quot;Horizontal lists inside Tabbed navigation screens&quot; /&gt;&lt;/p&gt;
&lt;p&gt;How do you switch between Tabs? You swipe. Horizontally. How do you scroll the list? Horizontally. Can you see that one gesture is used for two different actions? When used in Tabs, differentiate between horizontal scrolling and swiping. You don&apos;t want users to scroll to the end of a horizontal list, and then be taken to the next Tab. So what can we do? The easiest solution is to disable horizontal Tab swiping. The hardest solution is to rethink your navigation.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Horizontal List Alternative&lt;/h3&gt;
&lt;p&gt;The very purpose of a horizontal list is to show similar content that belongs to a particular category. Most apps who do this, display N scrollable items for a category. The remaining contents are hidden behind the SEE ALL button. So either way, you’re not showing ALL contents of a category. Assuming you display 10, users will have to tap ‘See All’ to view the remaining 50 plus whatever contents. If that’s what your horizontal list does, you don’t need a horizontal list at all.&lt;/p&gt;
&lt;h4&gt;Use a Grid instead&lt;/h4&gt;
&lt;p&gt;With no horizontal scrolling, users can now skim through your content faster. They just have to scroll in one direction. Vertically. We have already seen how Tablet designs adapt to this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./horizontal-scrolling-lists-mobile-best-practices/horizontal-lists-alternative.png&quot; alt=&quot;&quot; title=&quot;Horizontal list alternatives - using 2 row grids&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The second example is even better. Google Play Music app does it very well. It shows 4 contents of a playlist, collaged together. You can access other music in the playlist by directly tapping the thumbnail itself.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./horizontal-scrolling-lists-mobile-best-practices/horizontal-list-alternative-play-music.png&quot; alt=&quot;&quot; title=&quot;Google Play Music app&quot; /&gt;&lt;/p&gt;
&lt;p&gt;There are two advantages to this design decision:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;you retain the user’s natural flow of consuming content&lt;/li&gt;
&lt;li&gt;a user sees more initial content, than what a horizontal list shows&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Speaking of the second point, you may argue that a horizontal list shows more. Okay, I agree. But you need to scroll to see that don’t you? The point of an alternative is for you to rethink. Do you really need those nested, horizontal scrolling lists? Users naturally scroll vertical by default. I say this multiple times because anything that breaks this flow, breaks the ability to skim quickly through content. So before you decide upon horizontal lists, it&apos;s worth weighing its negatives. Otherwise, before going with it, you can always try one of the methods above.&lt;/p&gt;
&lt;h3&gt;Tip for Android Devs.&lt;/h3&gt;
&lt;p&gt;Embedding a horizontally scrollable list in a vertical parent list is hard. In other words, nesting RecyclerView is easy to do, but difficult to get it right. But don’t sweat it. Nick Butcher has done this for Google’s I/O 2016 app and open-sourced it! It includes some neat performance tweaks too. You can &lt;a href=&quot;https://github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/explore/ExploreIOFragment.java#L299&quot;&gt;see it on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; If you want to display different categories of a content, consider using horizontal lists. However, don’t include it in screens that belong to Tabbed navigation.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Today, content-heavy apps use nested scrolling with horizontal lists. While that&apos;s not wrong, it&apos;s implementation must be right. Horizontal scrolling feels more intuitive on mobile due to gestures. But use it with caution, because it breaks our natural flow of consuming content. Which is reading vertically. So make sure you have good reason to include it in your app. Remember at the start of this article, we talked about Google’s Play Store app. We also saw why using a horizontal list is suitable in their scenario. As UI/ UX designers, it&apos;s our responsibility to ensure that we don&apos;t confuse users. After all, scrolling is the most fundamental and highly-used gesture on mobile!&lt;/p&gt;
</content:encoded></item><item><title>Android Image Gallery App: Using Gestures and Transition</title><link>https://blog.iamsuleiman.com/android-image-gallery-app-gestures-transition/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/android-image-gallery-app-gestures-transition/</guid><description>In this post, we&apos;ll look at creating a Material Design style, image Gallery app for Android. It will support image gestures like zoom, as well as shar</description><pubDate>Tue, 25 Apr 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In this post, we&apos;ll look at creating a Material Design style, image Gallery app for Android. It will support image gestures like zoom, as well as shared element transitions. This is part two of the &lt;a href=&quot;https://blog.iamsuleiman.com/image-gallery-app-android-studio-1-4-glide/&quot;&gt;Create an Image Gallery App with Android Studio and Glide&lt;/a&gt; post. Previously, we created an Image Gallery app using &lt;strong&gt;Glide&lt;/strong&gt; and Android Studio templates. If you&apos;re not familiar with the basics, I strongly recommend you &lt;a href=&quot;https://blog.iamsuleiman.com/image-gallery-app-android-studio-1-4-glide/&quot;&gt;read part one&lt;/a&gt;. It will give you a solid understanding of &lt;strong&gt;Glide&lt;/strong&gt; and Layout Managers. One of the most commonly used apps on Android is the image gallery app. Have you ever wondered, how images are displayed in a continuous list? What about using gestures such as pinch zoom on images? In this post, we will learn how to implement exactly these. We will also take a dive into shared element transitions and learn how to use it for Fragments. We will also use a custom view called &lt;strong&gt;PhotoView&lt;/strong&gt; which can be used in placed of the regular ImageView. I&apos;ll show you how awesome PhotoView is soon.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Creating the Image Gallery App&lt;/h2&gt;
&lt;p&gt;We will be using 2 popular libraries in our gallery.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Glide&lt;/strong&gt; - powerful, yet simple to use image loading library by Square.Inc&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PhotoView&lt;/strong&gt; - flexible ImageView that supports gestures such as zoom and pan&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So first, let&apos;s start by adding the above dependencies. Add the following lines to your app&apos;s &lt;strong&gt;&lt;em&gt;build.gradle&lt;/em&gt;&lt;/strong&gt; file.&lt;/p&gt;
&lt;p&gt;repositories {&lt;br /&gt;
maven {
url &quot;&lt;a href=&quot;https://jitpack.io&quot;&gt;https://jitpack.io&lt;/a&gt;&quot;
}
}
dependencies {&lt;br /&gt;
...&lt;br /&gt;
compile &apos;com.squareup.picasso:picasso:2.5.2&apos;&lt;br /&gt;
compile &apos;com.github.chrisbanes:PhotoView:2.0.0&apos;
}&lt;/p&gt;
&lt;p&gt;First off, we need to create a model class for our images.&lt;/p&gt;
&lt;p&gt;public class ImageModel implements Parcelable {&lt;/p&gt;
&lt;p&gt;private String name, url;&lt;/p&gt;
&lt;p&gt;//TODO: Add your Getters and setters here.
}&lt;/p&gt;
&lt;p&gt;Next up, we need to create our &lt;code&gt;Activity.&lt;/code&gt; The only one that we will be using in this Android tutorial. We will use Fragments to handle everything else. We will create an &apos;&lt;em&gt;Empty Activity&lt;/em&gt;&apos; using Android Studio. Let&apos;s call it &lt;strong&gt;&lt;em&gt;MainActivity&lt;/em&gt;&lt;/strong&gt; as per convention.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Utility class for Image loading&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Before we go ahead and code, we&apos;ll create a utility class. This will provide us with the image data. We could keep this code inside an Activity too, but using a separate utility class helps keep our code clean.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Utils {

    static String IMGS\[\] = {
            &quot;https://images.unsplash.com/photo-1444090542259-0af8fa96557e&quot;,
            &quot;https://images.unsplash.com/photo-1439546743462-802cabef8e97&quot;,
            &quot;https://images.unsplash.com/photo-1441155472722-d17942a2b76a&quot;,
            .
            //more image links
    };

    public static ArrayList&amp;lt;ImageModel&amp;gt; getData() {
        ArrayList&amp;lt;ImageModel&amp;gt; arrayList = new ArrayList&amp;lt;&amp;gt;();
        for (int i = 0; i &amp;lt; IMGS.length; i++) {
            ImageModel imageModel = new ImageModel();
            imageModel.setName(&quot;Image &quot; + i);
            imageModel.setUrl(IMGS\[i\]);
            arrayList.add(imageModel);
        }
        return arrayList;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Defining Click Interface for Gallery Images&lt;/h4&gt;
&lt;p&gt;To handle clicks on images in the gallery, we will create a simple interface. This will help listen to click events.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface GalleryItemClickListener {
    void onGalleryItemClickListener(int position, ImageModel imageModel, ImageView imageView);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;Creating the Image Gallery Adapter&lt;/h5&gt;
&lt;p&gt;Next, we need to create an adapter that will handle the &lt;code&gt;RecyclerView&lt;/code&gt; data and display it. &lt;code&gt;RecyclerView&lt;/code&gt; offers powerful list and grid display options via &lt;code&gt;LayoutManager&lt;/code&gt;. You can learn &lt;a href=&quot;https://blog.iamsuleiman.com/pinterest-masonry-layout-staggered-grid/&quot;&gt;about RecyclerView&apos;s LayoutManager via the Staggered Grid article&lt;/a&gt;. So here&apos;s how we define our &lt;code&gt;RecyclerView.Adapter&lt;/code&gt;. It&apos;s very basic. Almost like how every standard adapter would be.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class GalleryAdapter extends RecyclerView.Adapter&amp;lt;GalleryAdapter.GalleryViewHolder&amp;gt; {

    private final GalleryItemClickListener galleryItemClickListener;
    private ArrayList&amp;lt;ImageModel&amp;gt; galleryList;

    public GalleryAdapter(ArrayList&amp;lt;ImageModel&amp;gt; galleryList, GalleryItemClickListener galleryItemClickListener) {
        this.galleryList = galleryList;
        this.galleryItemClickListener = galleryItemClickListener;
    }

    @Override
    public GalleryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new GalleryViewHolder(LayoutInflater.from(parent.getContext())
        .inflate(R.layout.gallery_item, parent, false));
    }

    @Override
    public void onBindViewHolder(final GalleryViewHolder holder, int position) {
        final ImageModel imageModel = galleryList.get(position);

        Glide.with(holder.galleryImageView.getContext()).
                load(imageModel.getUrl())
                .thumbnail(0.5f)
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .into(holder.galleryImageView);

        holder.galleryImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                galleryItemClickListener.onGalleryItemClickListener(holder.getAdapterPosition(), imageModel, holder.galleryImageView);
            }
        });
    }

    @Override
    public int getItemCount() {
        return galleryList.size();
    }

    static class GalleryViewHolder extends RecyclerView.ViewHolder {
        private ImageView galleryImageView;

        GalleryViewHolder(View view) {
            super(view);
            galleryImageView = (ImageView) view.findViewById(R.id.galleryImage) ;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The layout of the &lt;code&gt;RecyclerView&lt;/code&gt; items is as follows.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;ImageView xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
android:id=&quot;@+id/galleryImage&quot;
android:layout_width=&quot;match_parent&quot;
android:layout_height=&quot;128dp&quot;
android:layout_margin=&quot;1dp&quot;
android:adjustViewBounds=&quot;true&quot;
android:scaleType=&quot;centerCrop&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nothing fancy till now. We have created a regular &lt;code&gt;RecyclerView.Adapter&lt;/code&gt;. This uses an interface to handle click events. Then we use &lt;code&gt;Glide&lt;/code&gt; to load the image into our &lt;code&gt;ImageView&lt;/code&gt;. You can however save yourself trouble and NOT write RecyclerView.Adapter boilerplate code. Learn to use &lt;a href=&quot;https://blog.iamsuleiman.com/recyclerview-adapter-android-made-fast-easy/&quot;&gt;FastAdapter to write easier, smaller and faster RecyclerView Adapter code&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Using Fragments instead of Activities&lt;/h2&gt;
&lt;p&gt;Now that our Adapter is complete, we need to create a &lt;code&gt;Fragment&lt;/code&gt; to hold our &lt;code&gt;RecyclerView&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;public class RecyclerViewFragment extends Fragment {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static final String TAG = RecyclerViewFragment.class.getSimpleName();

public RecyclerViewFragment() {
}

public static RecyclerViewFragment newInstance() {
    return new RecyclerViewFragment();
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_recycler_view, container, false);
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    GalleryAdapter galleryAdapter = new GalleryAdapter(Utils.getData(),this);
    RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
    GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), 2);
    recyclerView.setLayoutManager(gridLayoutManager);
    recyclerView.setAdapter(galleryAdapter);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In the &lt;code&gt;onViewCreated()&lt;/code&gt; method, we create our &lt;code&gt;RecyclerView.Adapter&lt;/code&gt; (&lt;em&gt;GalleryAdapter&lt;/em&gt;). Notice that &lt;code&gt;Utils.getData()&lt;/code&gt; provides a list of images which we populated. Next, we create a &lt;a href=&quot;https://developer.android.com/reference/android/support/v7/widget/GridLayoutManager.html&quot;&gt;&lt;code&gt;GridLayoutManager&lt;/code&gt;&lt;/a&gt; which consists of two columns. Finally, we attach the adapter and &lt;code&gt;LayoutManager&lt;/code&gt; to &lt;code&gt;RecyclerView&lt;/code&gt;. Another type of &lt;code&gt;GridLayoutManger&lt;/code&gt; is the &lt;code&gt;StaggeredGridLayoutManager&lt;/code&gt;. The &lt;a href=&quot;https://blog.iamsuleiman.com/pinterest-masonry-layout-staggered-grid/&quot;&gt;Pinterest Android app uses this and you can learn how to do it too&lt;/a&gt;. Here&apos;s the Fragment XML layout.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;android.support.v7.widget.RecyclerView
    android:id=&quot;@+id/recycler_view&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    android:clipToPadding=&quot;false&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, let&apos;s launch the &lt;em&gt;RecyclerViewFragment&lt;/em&gt; from our &lt;em&gt;MainActivity&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;public class MainActivity extends AppCompatActivity {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override
protected void onCreate(Bundle savedInstanceState) {

    getSupportFragmentManager()
            .beginTransaction()
            .add(R.id.content, RecyclerViewFragment.newInstance())
            .commit();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Our gallery view is ready. Now if you run the code, you should get something like this&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-image-gallery-app-gestures-transition/Gallery.png&quot; alt=&quot;Gallery View&quot; title=&quot;Gallery View&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Launching Full-screen Gallery Images&lt;/h2&gt;
&lt;p&gt;Now we will start implementing the view where can see the images in fullscreen. We will use a &lt;code&gt;Fragment&lt;/code&gt; to display each image. Let&apos;s call this &lt;code&gt;Fragment&lt;/code&gt; &lt;em&gt;&lt;strong&gt;ImageDetailFragment&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;public class ImageDetailFragment extends Fragment {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static final String EXTRA_IMAGE = &quot;image_item&quot;;

public ImageDetailFragment() {
    // Required empty public constructor
}

public static ImageDetailFragment newInstance(ImageModel image) {
    ImageDetailFragment fragment = new ImageDetailFragment();
    Bundle args = new Bundle();
    args.putParcelable(EXTRA_IMAGE, image);
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_image_detail, container, false);
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    final ImageModel image = getArguments().getParcelable(EXTRA_IMAGE);

    final PhotoView imageView = (PhotoView) view.findViewById(R.id.detail_image);
  
    Glide.with(getActivity())
            .load(image.getUrl())
            .asBitmap()
            .into(new SimpleTarget&amp;lt;Bitmap&amp;gt;() {
                @Override
                public void onResourceReady(Bitmap resource, GlideAnimation&amp;lt;? super Bitmap&amp;gt; glideAnimation) {
                    startPostponedEnterTransition();
                    imageView.setImageBitmap(resource);
                }
            });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The layout for &lt;em&gt;&lt;strong&gt;fragment_image_detail.xml&lt;/strong&gt;&lt;/em&gt; is as follows.&lt;/p&gt;
&lt;p&gt;&amp;lt;com.github.chrisbanes.photoview.PhotoView xmlns:android=&quot;&lt;a href=&quot;http://schemas.android.com/apk/res/android&quot;&gt;http://schemas.android.com/apk/res/android&lt;/a&gt;&quot;
android:id=&quot;@+id/detail_image&quot;
android:layout_width=&quot;match_parent&quot;
android:layout_height=&quot;wrap_content&quot;
android:adjustViewBounds=&quot;true&quot;
android:scaleType=&quot;fitCenter&quot; /&amp;gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Adding Gesture Support to ImageView&lt;/h2&gt;
&lt;p&gt;Here is where we make use of the awesome &lt;code&gt;**PhotoView**&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PhotoView&lt;/code&gt; allows us to add like features pinch to zoom, double tap to zoom. We use &lt;code&gt;PhotoView&lt;/code&gt; in place of ImageView and that&apos;s it. We&apos;ll have a functional &lt;code&gt;ImageView&lt;/code&gt; that supports gestures. Pretty easy right?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A word of caution&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Notice that we didn&apos;t load the image from URL into &lt;code&gt;ImageView&lt;/code&gt;. The image is first downloaded as a &lt;code&gt;Bitmap&lt;/code&gt; and then loaded into &lt;code&gt;ImageView&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is a restriction imposed when we use PhotoView along with Glide. But don&apos;t worry, it&apos;s a tiny workaround for an amazing result!&lt;/p&gt;
&lt;h3&gt;Swiping Images in Fragment - ViewPager&lt;/h3&gt;
&lt;p&gt;To get swipeable slides of images likes the one seen in galleries, we can use a &lt;code&gt;**ViewPager**&lt;/code&gt;. It is a widget available in the Android Support Library. Just like we need an adapter for a &lt;code&gt;RecyclerView&lt;/code&gt;, we need one for our &lt;code&gt;ViewPager&lt;/code&gt; too. Let&apos;s name ours &lt;em&gt;&lt;strong&gt;GalleryPagerAdapter&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;public class GalleryPagerAdapter extends FragmentStatePagerAdapter {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private ArrayList&amp;lt;ImageModel&amp;gt; images;

public GalleryPagerAdapter(FragmentManager fm, ArrayList&amp;lt;ImageModel&amp;gt; images) {
    super(fm);
    this.images = images;
}

@Override
public Fragment getItem(int position) {
    ImageModel image = images.get(position);
    return ImageDetailFragment.newInstance(image);
}

@Override
public int getCount() {
    return images.size();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In the &lt;code&gt;getItem()&lt;/code&gt; method, you can see that it returns an instance of &lt;em&gt;ImageDetailFragment&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;This is how &lt;code&gt;ViewPager&lt;/code&gt; works. They contain a series of Fragments of the same type. That&apos;s what allows us to swipe across various slides (images in our case).&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ViewPager&lt;/code&gt; creates 3 instances of the &lt;code&gt;Fragment&lt;/code&gt; to display, every time we view a slide. One to the left of the current slide and one to the right. Such a mechanism ensures a smooth scroll between slides. The good news is that this is internally handled. So you don&apos;t have to worry about it.&lt;/p&gt;
&lt;p&gt;Ideally, we use &lt;code&gt;ViewPager&lt;/code&gt; along with Tabs. This &lt;a href=&quot;https://blog.iamsuleiman.com/material-design-tabs-with-android-design-support-library/&quot;&gt;tutorial can teach you how to use Android ViewPager with Material Design Tabs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now the final piece left for our image gallery app is the &lt;code&gt;Fragment&lt;/code&gt; to handle the &lt;code&gt;ViewPager&lt;/code&gt;. We will call it &lt;em&gt;GalleryViewPagerFragment&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;public class GalleryViewPagerFragment extends Fragment {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static final String EXTRA_INITIAL_POS = &quot;initial_pos&quot;;
private static final String EXTRA_IMAGES = &quot;images&quot;;

public GalleryViewPagerFragment() {
}

public static GalleryViewPagerFragment newInstance(int current, ArrayList&amp;lt;ImageModel&amp;gt; images) {
    GalleryViewPagerFragment fragment = new GalleryViewPagerFragment();
    Bundle args = new Bundle();
    args.putInt(EXTRA_INITIAL_POS, current);
    args.putParcelableArrayList(EXTRA_IMAGES, images);
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_gallery_view_pager, container, false);
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    int currentItem = getArguments().getInt(EXTRA_INITIAL_POS);
    ArrayList&amp;lt;ImageModel&amp;gt; images = getArguments().getParcelableArrayList(EXTRA_IMAGES);

    GalleryPagerAdapter galleryPagerAdapter = new GalleryPagerAdapter(getChildFragmentManager(), images);
    ViewPager viewPager = (ViewPager) view.findViewById(R.id.animal_view_pager);
    viewPager.setAdapter(galleryPagerAdapter);
    viewPager.setCurrentItem(currentItem);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In &lt;code&gt;onViewCreated()&lt;/code&gt;, we create a &lt;code&gt;ViewPager&lt;/code&gt; object. Then we set an instance of &lt;em&gt;GalleryPagerAdapter&lt;/em&gt; as its Adapter.&lt;/p&gt;
&lt;h4&gt;Handling Clicks; Launching the Detail View&lt;/h4&gt;
&lt;p&gt;Now that all the required classes have been created, we have one tiny thing left. Yes, you guessed it right. We have to launch the &lt;code&gt;ViewPager&lt;/code&gt; when an image in the gallery view is clicked. That&apos;s really simple. We need to use the &lt;code&gt;onGalleryItemClickListener&lt;/code&gt; interface. So go ahead and implement that in &lt;em&gt;RecyclerViewFragment&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;public class RecyclerViewFragment extends Fragment implements GalleryItemClickListener{&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static final String TAG = RecyclerViewFragment.class.getSimpleName();

@Override
public void onGalleryItemClickListener(int position, ImageModel imageModel, ImageView imageView) {

    GalleryViewPagerFragment galleryViewPagerFragment = GalleryViewPagerFragment.newInstance(position, Utils.getData());

    getFragmentManager()
            .beginTransaction()
            .addToBackStack(TAG)
            .replace(R.id.content, galleryViewPagerFragment)
            .commit();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Since we&apos;re working with Fragments, the back press by default works for &lt;code&gt;Activity&lt;/code&gt; only &lt;strong&gt;&lt;code&gt;addToBackStack()&lt;/code&gt;&lt;/strong&gt; remembers the &lt;code&gt;Fragment&lt;/code&gt; we added. So now when we press the Back button, we go back to the gallery view, instead of exiting the app. That&apos;s it! You have now created a fully functional image gallery app. We saw how to display images from the internet using &lt;code&gt;Glide&lt;/code&gt;. Additionally, we also added gesture capability such as zoom and pan using &lt;code&gt;PhotoView&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Shared Element Transition&lt;/h3&gt;
&lt;p&gt;Lastly, don&apos;t forget that I promised animations. Material Design brought in a new type of transition called &lt;strong&gt;Shared Element Transition&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The transition focuses on content and its representation in the new activity. Such a transition makes the experience a lot more seamless.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A transition when two screens (Activities or Fragments) share one or more common views. But, it is available only on API level 21 and above. Remember this. You need to properly &lt;a href=&quot;https://blog.iamsuleiman.com/android-material-design-tutorial/&quot;&gt;setup an Android project theme styles to use Material Design&lt;/a&gt;. Alternatively, you can &lt;a href=&quot;https://blog.iamsuleiman.com/material-design-starter-project-for-android-studio/&quot;&gt;use this free Material Design starter project&lt;/a&gt;. It has everything configured, so you can start building your app right away. So let&apos;s get started and add shared element transitions to our gallery app. The way shared element transitions work is that a shared view has a unique transition name. This allows the view to be shared during the transition. We add this transition name in the &lt;em&gt;GalleryAdapter&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;public class GalleryAdapter extends RecyclerView.Adapter&amp;lt;GalleryAdapter.GalleryViewHolder&amp;gt; {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override
public void onBindViewHolder(final GalleryViewHolder holder, int position) {
    final ImageModel imageModel = galleryList.get(position);

    // Set transition name same as the Image name
    ViewCompat.setTransitionName(holder.galleryImageView, imageModel.getName());

    holder.galleryImageView.setOnClickListener(new View.OnClickListener() {
        .
    });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;We set the transition name as the image name. This ensures that the transition name is unique for all the images in the gallery.&lt;/p&gt;
&lt;p&gt;When we call our &lt;code&gt;ViewPager&lt;/code&gt; from the &lt;code&gt;RecyclerView&lt;/code&gt;, we need to mention the shared &lt;code&gt;View&lt;/code&gt;. In other words, the &lt;code&gt;View&lt;/code&gt; being shared with the &lt;code&gt;ViewPager&lt;/code&gt;. We do this by using the &lt;strong&gt;&lt;code&gt;addSharedElement()&lt;/code&gt;&lt;/strong&gt; method.&lt;/p&gt;
&lt;p&gt;public class RecyclerViewFragment extends Fragment implements GalleryItemClickListener{&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override
public void onGalleryItemClickListener(int position, ImageModel imageModel, ImageView imageView) {
    GalleryViewPagerFragment galleryViewPagerFragment = GalleryViewPagerFragment.newInstance(position, Utils.getData());

    getFragmentManager()
            .beginTransaction()
            .addSharedElement(imageView, ViewCompat.getTransitionName(imageView))
            .addToBackStack(TAG)
            .replace(R.id.content, galleryViewPagerFragment)
            .commit();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;addSharedElement()&lt;/code&gt; method takes a &lt;code&gt;View&lt;/code&gt; and its transition name as parameters. So now we have told our &lt;code&gt;FragmentManager&lt;/code&gt; about the transition. Next, we have to notify the &lt;em&gt;ImageDetailFragment&lt;/em&gt; about the transition. We also need to include a parameter for the transition name.&lt;/p&gt;
&lt;p&gt;public class ImageDetailFragment extends Fragment {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static final String EXTRA_TRANSITION_NAME= &quot;transition_name&quot;;

public static ImageDetailFragment newInstance(ImageModel image, String transitionName) {
    ImageDetailFragment fragment = new ImageDetailFragment();
    Bundle args = new Bundle();
    args.putParcelable(EXTRA_IMAGE, image);
    args.putString(EXTRA_TRANSITION_NAME, transitionName);
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    String transitionName = getArguments().getString(EXTRA_TRANSITION_NAME);

    if (Build.VERSION.SDK_INT &amp;gt;= Build.VERSION_CODES.LOLLIPOP) {
        imageView.setTransitionName(transitionName);
    }

    ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;That&apos;s it. Our shared element transition should work. But wait, there is a small glitch!&lt;/p&gt;
&lt;h4&gt;Achieving Smoother Transitions&lt;/h4&gt;
&lt;p&gt;If you run the app now, you will notice that we do not get any smooth transition. This is because it is overridden by the default &lt;code&gt;Fragment&lt;/code&gt; transition. So we need a way to delay the enter transition for the Fragments. We can do so in the &lt;code&gt;onCreate()&lt;/code&gt; methods of &lt;em&gt;ImageDetailFragment&lt;/em&gt; and &lt;em&gt;GalleryViewPagerFragment&lt;/em&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; @Override
 public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     postponeEnterTransition();
     if (Build.VERSION.SDK_INT &amp;gt;= Build.VERSION_CODES.LOLLIPOP) {       
        setSharedElementEnterTransition(
              TransitionInflater.from(getContext())
                    .inflateTransition(android.R.transition.move)
              );
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You will notice that there&apos;s an API level check. This is done to ensure backwards compatibility. Remember that Shared Element Transitions are available only in API level 21+. And finally, our app is ready!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/android-image-gallery-app-gestures-transition/gallery-gif.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The source code for the app is available on &lt;a href=&quot;https://github.com/SubhrajyotiSen/GlideGallery&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Wrap up&lt;/h2&gt;
&lt;p&gt;In this post, we learnt how to create a gallery view step by step. We also learnt about &lt;code&gt;PhotoView&lt;/code&gt; and how to use it in our app to get some amazing gesture support. We implemented shared element transition between our two screens to give the feel of a continuous UI. Did you like &lt;code&gt;PhotoView&lt;/code&gt;? Will you be using shared element transitions in your app? I would love to hear from you in the comments below.&lt;/p&gt;
</content:encoded></item><item><title>Design Techniques to Display Text over Background Images</title><link>https://blog.iamsuleiman.com/techniques-to-display-text-overlay-background-images/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/techniques-to-display-text-overlay-background-images/</guid><description>It&apos;s become popular to overlay text labels on background images. But the image could be anything. How does your user interface design accommodate that</description><pubDate>Tue, 11 Apr 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It&apos;s become popular to overlay text labels on background images. But the image could be anything. How does your user interface design accommodate that? Can text overlay remain readable always?&lt;/p&gt;
&lt;p&gt;The last thing you&apos;d want is your users straining to read such text. This is all the more important on mobile. Smaller screens and smaller text make it slightly harder to read.&lt;/p&gt;
&lt;p&gt;But don&apos;t worry. There are a couple of design techniques you can follow to ensure that.&lt;/p&gt;
&lt;p&gt;First, let me show you some design mockups that use text overlay.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./techniques-to-display-text-overlay-background-images/portfolio-page.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Photography Portfolio by Winart Foster on Dribbble&lt;/p&gt;
&lt;p&gt;Here&apos;s another.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./techniques-to-display-text-overlay-background-images/article_cards.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Article Cards Alternate by Oliur on Dribbble&lt;/p&gt;
&lt;p&gt;A good eye will immediately notice the problem with these two designs. Take the second one with the sea waves. If the wave foam was on the lower half of the image, would that text be readable?&lt;/p&gt;
&lt;p&gt;Let me try to recreate that design for you.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./techniques-to-display-text-overlay-background-images/scrim-before-after-eg.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Text with scrim overlay&lt;/p&gt;
&lt;p&gt;How readable is the text now?&lt;/p&gt;
&lt;p&gt;Alright, its not the same picture. But it&apos;s still ocean waves.&lt;/p&gt;
&lt;p&gt;The background image is outright disturbing. But the image is not to blame. After all, when you decide to overlay text, you must be ready for ANY image. Which means, the image could be anything.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Good design is when we factor in all possible scenarios.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now don&apos;t get me wrong. Those 2 designs are not bad in any way. In fact, I love the typography used in the second one. Both are well-designed interfaces by talented people. It&apos;s just that, some interface designs (mockups) are only for aesthetic purposes.&lt;/p&gt;
&lt;p&gt;Anyone who translates them into a working project will immediately recognize what&apos;s wrong. The text displayed, does not account for its background images.&lt;/p&gt;
&lt;p&gt;However these mockups are only examples. It assumes that whatever be the image, the text will be readable. But my design attempt just showed you that that&apos;s not the case.&lt;/p&gt;
&lt;h2&gt;The 2-in-1 problem with text overlay&lt;/h2&gt;
&lt;p&gt;Now we could say that this pattern became overly popular thanks to Card design. I mean, most of the card designs include an image, with text overlaid on top. Not to say that its bad, but there are two things that are largely not considered.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://material.uplabs.com/posts/trip-detail-card&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://material.uplabs.com/posts/trip-detail-card&quot;&gt;Trip detail card by Harsheen Kaur&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When you overlay text on an image, you sacrifice two things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Image clarity&lt;/li&gt;
&lt;li&gt;Text readability&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Readability is the ease with which a reader can understand a written text. It is a measure of how easily a reader can distinguish individual letters or characters from each other. - Wikipedia&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Overlaying a text prevents viewing the image completely. Moreover, your text may not be readable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The image can be anything&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now, most of the examples above are mockups. Which means those are ideal scenarios. The text matches perfectly against its background. Things can immediately go wrong if your using white text over a whitish or light image. The same holds true for black or darker tones.&lt;/p&gt;
&lt;p&gt;Now we know the mess we’re getting ourselves into. So let’s look at what we can do about it.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Text Overlay Solutions&lt;/h3&gt;
&lt;p&gt;There are different approaches to making our overlay text readable. I want you to understand that these are different solutions to a single problem. There is no single solution answer.&lt;/p&gt;
&lt;p&gt;Moreover, deciding on what to use ultimately boils down to your personal preference. Or you can even decide upon one, depending on what fits your brand style.&lt;/p&gt;
&lt;h4&gt;1. Using a Scrim&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;A Scrim is a semi-transparent gradient layer that helps Text appear more readable against backgrounds.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A scrim is a solid to a transparent gradient that sits behind a Text Label. So for instance, your text label could be a constant white. Then, your scrim would be a gradient going from, say 40% black to transparent.&lt;/p&gt;
&lt;p&gt;I leave the opacity percentage to you. Again that’s a matter of personal taste.&lt;/p&gt;
&lt;p&gt;But a 40% black to transparent works really well. It&apos;s not too evident and doesn’t disturb the image. It fades smoothly, giving the text label the contrast it needs, making it readable.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./techniques-to-display-text-overlay-background-images/scrim-do-dont.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Scrim - gradient overlay&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Scrim guidelines:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;40% opacity&lt;/li&gt;
&lt;li&gt;gradient settings&lt;/li&gt;
&lt;li&gt;height: 50% of image height&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are not hard rules. But as you can see from the above design, these settings work well.&lt;/p&gt;
&lt;p&gt;You can read about this in the &lt;a href=&quot;https://material.io/guidelines/style/imagery.html&quot;&gt;Material Design Imagery guidelines&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./techniques-to-display-text-overlay-background-images/scrim-black-gradient-sketch.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Scrim gradient settings in Sketch&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Advantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Most simple and common solution&lt;/li&gt;
&lt;li&gt;Increases contrast for better text readability&lt;/li&gt;
&lt;li&gt;A subtle design change which is hardly noticeable&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Disadvantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sharp gradients can break the image&apos;s appeal&lt;/li&gt;
&lt;li&gt;Can block the image if visibility is too high&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By far, using a scrim is the most popular solution for solving the text overlay issue with images.&lt;/p&gt;
&lt;p&gt;But wait, don’t go yet! There are other solutions which might suit your taste better.&lt;/p&gt;
&lt;h4&gt;2. Overlay the entire image&lt;/h4&gt;
&lt;p&gt;Like the scrim solution, and instead of a gradient, you’d apply a full 40% black to the whole image.&lt;/p&gt;
&lt;p&gt;That’s right. Maybe the image isn’t important to you. The text label is your priority. Or maybe the text covers the entire image’s size.&lt;/p&gt;
&lt;p&gt;In such a situation, using a scrim doesn’t make sense. Since the scrim is a gradient, your text becomes unreadable half-way across.&lt;/p&gt;
&lt;p&gt;So since the text covers the whole image, the solution is to darken the entire image.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./techniques-to-display-text-overlay-background-images/full-overlay-do-dont.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In short, that&apos;s a 40% opacity black on the image.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Advantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Useful for large text (headings?) that covers the entire image&lt;/li&gt;
&lt;li&gt;When text is your priority and not the image&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Disadvantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Can obscure the entire image&lt;/li&gt;
&lt;li&gt;Could sacrifice image visibility&lt;/li&gt;
&lt;li&gt;Can diminish the background image as if it exists only for aesthetics&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here are some popular apps that use this approach:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./techniques-to-display-text-overlay-background-images/full-image-scrim.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Medium Series on Android&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://material.uplabs.com/posts/85000-status-and-quotes-2017-android-app&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;85000+ Status and Quotes 2017 Android App by Pratik Butani&lt;/p&gt;
&lt;h4&gt;3. Color Overlay&lt;/h4&gt;
&lt;p&gt;This is like an overlay. But instead of using black or white to darken or lighten the image, we use a different color.&lt;/p&gt;
&lt;p&gt;Setting a &lt;strong&gt;color overlay&lt;/strong&gt; on an image is the perfect way to neutralize a busy image. It blocks out all the different colors, making the image monotone.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./techniques-to-display-text-overlay-background-images/color-overlay-do-dont.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Here is an example.&lt;/p&gt;
&lt;p&gt;Usually, the color of choice is the brand color.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./techniques-to-display-text-overlay-background-images/playgong.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Playgong App by Deividas Graužinis&lt;/p&gt;
&lt;p&gt;If you have trouble deciding color, check out &lt;a href=&quot;https://www.canva.com/colors/color-wheel/&quot;&gt;Canva&apos;s Color Wheel Tool&lt;/a&gt;. It uses color theory and color combinations in design to help you find colors that look good together!&lt;/p&gt;
&lt;h4&gt;4. Soft gradients&lt;/h4&gt;
&lt;p&gt;Remember that to use this correctly, your text should have enough contrast.&lt;/p&gt;
&lt;p&gt;Also, when you use gradients, don&apos;t use visually jarring colors. Chose colors that work together in harmony.&lt;/p&gt;
&lt;p&gt;You can use web tools such as &lt;a href=&quot;https://coolors.co/&quot;&gt;Coolors&lt;/a&gt; and &lt;a href=&quot;https://color.adobe.com/create/color-wheel/&quot;&gt;Kuler by Adobe&lt;/a&gt;. These can help you generate color pairs that work well together.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./techniques-to-display-text-overlay-background-images/gradient-do-dont.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Here&apos;s an example.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://material.uplabs.com/posts/web-agency&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Web Agency by Mohammad Shohag&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Advantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Better brand emphasis (if brand color used)&lt;/li&gt;
&lt;li&gt;Single color tone allows room for better text contrast&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Disadvantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Not suitable for pictures of people as it may not be recognizable&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;5. Semi-Transparent Image&lt;/h4&gt;
&lt;p&gt;This technique involves using a semi-transparent image against a solid color background. It helps ‘calm’ the noisy background, so the text can stand out.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./techniques-to-display-text-overlay-background-images/semitrans-do-dont.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The technique consists of 3 layers (from the bottom):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Bottom - solid color&lt;/li&gt;
&lt;li&gt;Middle - semi-transparent image (40% opacity)&lt;/li&gt;
&lt;li&gt;Top - Text layer&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Advantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Softer image allows text to stand out&lt;/li&gt;
&lt;li&gt;Makes image monotone, reducing image noise&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Disadvantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Image may lose important details&lt;/li&gt;
&lt;li&gt;Only suitable for images whose purpose is eye candy&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;6. Blur&lt;/h4&gt;
&lt;p&gt;Applying a Gaussian blur softens an image allowing text to become more readable.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Smoothing of images by reducing image noise and detail - Gaussian Blur&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;iOS folks will be familiar with this technique. iOS design principles use blur to denote depth. Whereas Android (Material Design) uses shadows to denote depth (elevation).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./techniques-to-display-text-overlay-background-images/blur-do-dont.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Here&apos;s a 16px blur on the left, and 4px blur on the right. Make sure you don&apos;t blur the image too much that the underlying image is completely unrecognizable!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./techniques-to-display-text-overlay-background-images/blur-same-color-problem.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Blur doesn&apos;t solve same text and image color problem&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Advantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Helps reduce the ‘busyness’ in images&lt;/li&gt;
&lt;li&gt;Softened images allow text to stand out&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Disadvantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Completely sacrifices the image for text&lt;/li&gt;
&lt;li&gt;Still doesn&apos;t solve same-color overlay issue&lt;/li&gt;
&lt;li&gt;May not suit your product style. Using blur in a Material Design world?&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;7. Text Highlight&lt;/h4&gt;
&lt;p&gt;Here, we apply a background color to the text itself. This effect mimics the traditional way of highlighting text on paper.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./techniques-to-display-text-overlay-background-images/text-highlight.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Text with Highlighter effect&lt;/p&gt;
&lt;p&gt;This technique works well when the design has minimal text and a spacious background.&lt;/p&gt;
&lt;p&gt;Remember that the highlight color doesn&apos;t always have to be black. The example on the right borrows the dominant color from the image. This creates a higher sense of belonging with the image.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Advantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Good text clarity against any background image&lt;/li&gt;
&lt;li&gt;Good contrast&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Disadvantages:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Choice of highlight color may make text feel disconnected from image&lt;/li&gt;
&lt;li&gt;Can completely block the underlying image&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;8. Go Grayscale&lt;/h4&gt;
&lt;p&gt;Alright, this is more of altering the image than the text. But we can still use it to achieve what we want.&lt;/p&gt;
&lt;p&gt;By using a grayscale image.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./techniques-to-display-text-overlay-background-images/greyscale-img.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Greyscale image filter&lt;/p&gt;
&lt;p&gt;However, remember that greyscale includes colors from the brightest white to the darkest black. These alone, are on the polar ends of vibrancy. Hence you might want to consider toning down the image first. You can do so via a mix and match with any other techniques mentioned here.&lt;/p&gt;
&lt;p&gt;For example, here&apos;s a grayscale image with text at the bottom. However, by default this wouldn&apos;t look good. So we add a scrim at the bottom.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./techniques-to-display-text-overlay-background-images/greyscale-mix-match-img.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Greyscale image with bottom Scrim combined&lt;/p&gt;
&lt;p&gt;Notice how the scrim naturally blends very well with the image. The image is greyscale and our scrim is a black to transparent gradient. Hence the two techniques go hand-in-hand, quite well.&lt;/p&gt;
&lt;h4&gt;9. Playing with color and positioning&lt;/h4&gt;
&lt;p&gt;Sometimes, no matter what, the image remains the same. Say, for example, a category page will use a constant header image depicting its category.&lt;/p&gt;
&lt;p&gt;In such a situation, you know what image to expect. You can use this information to design your text. This can be the font, size, color or even positioning the text.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://material.uplabs.com/posts/universitet-modules&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Universitet Modules by Flatstudio&lt;/p&gt;
&lt;p&gt;Notice the smart positioning of text, away from images. Also, the calm pastel background colors are not distracting. Both work in favor of allowing the text to stand out in addition to the graphic.&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;TL;DR - Use enough contrast&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;The state of being strikingly different from something else in close association. - Contrast&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Did you notice? All the techniques discussed above are ways to increase text contrast. Contrast is what makes an element appear distinct from one another. There should be high contrast between text and image. It allows text to be readable.&lt;/p&gt;
&lt;p&gt;There is also no need to sacrifice image visibility for text. Both can coexist together if we use the right technique. For instance, using a scrim allows text to be readable. At the same time, the image is visible as well.&lt;/p&gt;
&lt;p&gt;As a general rule, using greyscale colors work well. Which means, white text against a dark background. Or black (dark grey) text against a light background always works best.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;We looked at techniques that make text readable, without sacrificing the background image. Techniques such as the scrim are perfect examples of this. Or, using a color overlay can help reinforce your brand by using its primary color. This is especially useful when the image feels out of place in your design. Moreover, the blur technique is useful as well. But you will have to see if it aligns with your design style.&lt;/p&gt;
&lt;p&gt;Remember that good design is thoughtful and knows how to balance aesthetic visuals with usability and clarity. It is not enough to let people use your app. It must be easy and pleasing to use.&lt;/p&gt;
&lt;p&gt;You can even mix and match two techniques. Your imagination is the limit. Color overlay with scrim anyone?&lt;/p&gt;
&lt;p&gt;So which technique are you going to use? Have I missed any popular method? I&apos;d love to hear your thoughts. Let&apos;s talk in the comments below.&lt;/p&gt;
</content:encoded></item><item><title>Android O Tutorial: Using Custom Font Resources</title><link>https://blog.iamsuleiman.com/android-o-tutorial-custom-font-resources/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/android-o-tutorial-custom-font-resources/</guid><description>One of the new features in Android O is using Custom Font Resources. In this Android Tutorial, let’s see how to use them in our apps. The first Androi</description><pubDate>Thu, 30 Mar 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;One of the new features in Android O is using Custom Font Resources. In this Android Tutorial, let’s see how to use them in our apps. The first Android O Developer Preview just dropped. &lt;a href=&quot;https://blog.iamsuleiman.com/android-o-what-developers-need-know/&quot;&gt;There’s a lot for us developers to know about&lt;/a&gt;. One of the highlights in Android O is the ability to use custom font resources. In this article let’s look at using custom fonts in our apps. Before Android O, how difficult was it to use a custom font in our apps? We had two options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Write a custom View&lt;/li&gt;
&lt;li&gt;Use a library&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Both options need considerable effort, for just a simple font. Extending your custom View in EVERY layout.xml, instead of TextView is tedious. Moreover, using a third-party library for something basic as text, can be a risky call. How many times have you admired a beautiful font, and wanted to use that in your app? But the sheer thought of integrating it, made you feel it&apos;s not worth it? Well, not anymore! Seeing Android O giving official support to custom fonts brought a big smile to my face. I hope it did to you as well.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Getting Started with Font Resources&lt;/h2&gt;
&lt;p&gt;Android O supports custom fonts via &lt;strong&gt;font resources&lt;/strong&gt;. The magic lies in the &lt;em&gt;app/res&lt;/em&gt; folder.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-o-tutorial-custom-font-resources/custom_font_new_android_resource_directory-e1490779280934.png&quot; alt=&quot;&quot; title=&quot;Create new resource directory in Android Studio&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Creating the font folder is easy. It is like every other resource such as menu, values, drawable, etc. So right click the &lt;em&gt;res&lt;/em&gt; folder and create a new &lt;strong&gt;&lt;em&gt;font&lt;/em&gt;&lt;/strong&gt; folder.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-o-tutorial-custom-font-resources/custom_font_resources_new_font_folder.png&quot; alt=&quot;&quot; title=&quot;Create a new font resource directory&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now you’re ready to drop in your fonts. So go ahead and pick a font of your choice. &lt;strong&gt;Font Formats&lt;/strong&gt; Android O supports both &lt;em&gt;.otf (OpenType)&lt;/em&gt; and &lt;em&gt;.ttf (TrueType)&lt;/em&gt; font formats. I’m going to create a simple page design. Like a book, where the heading is a large serif font.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-o-tutorial-custom-font-resources/custom_font_resources_op-copy.png&quot; alt=&quot;&quot; title=&quot;What we&apos;ll be creating&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Using Custom Font Resources in Android O&lt;/h3&gt;
&lt;p&gt;For this Android O tutorial, I’m going to pick my fonts from Google Fonts. They have a great collection, so definitely check that out! My two font choices are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://fonts.google.com/specimen/Merriweather&quot;&gt;Merriweather&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://fonts.google.com/specimen/Lato&quot;&gt;Lato&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here are the available font styles for Merriweather. I&apos;m happy with just the regular font so I&apos;ll take that alone.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-o-tutorial-custom-font-resources/font_resources_google_font_weights.png&quot; alt=&quot;&quot; title=&quot;Download font via fonts.google.com&quot; /&gt;&lt;/p&gt;
&lt;p&gt;You can download the &lt;em&gt;.otf&lt;/em&gt; or &lt;em&gt;.ttf&lt;/em&gt; fonts of your choice and drop them in the &lt;em&gt;res/fonts&lt;/em&gt; folder. &lt;strong&gt;Note:&lt;/strong&gt; Keep in mind, that resource files should use lowercase alphabets and underscores. For example, the downloaded font was &lt;em&gt;Merriweather-Regular.ttf.&lt;/em&gt; When you copy it to the &lt;em&gt;res/fonts&lt;/em&gt; folder, rename it to &lt;em&gt;merriweather_regular.ttf&lt;/em&gt;. Once you drop in your custom font files in the fonts folder, you can preview your fonts. Simply double-click on a font, and Android Studio previews the typeface. Neat right?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-o-tutorial-custom-font-resources/custom_font_resources_font_preview_android_studio.png&quot; alt=&quot;&quot; title=&quot;Font Typeface preview&quot; /&gt;&lt;/p&gt;
&lt;p&gt;We&apos;re going to need two fonts. One for the heading, and one for the body text. Look closely at the design above. The headline uses a &lt;em&gt;serif&lt;/em&gt; font, while the content body is a &lt;em&gt;sans-serif&lt;/em&gt;. In other words, the heading will use Merriweather while the content body will use Lato. Remember, I encourage you to use whatever you like. Feel free to experiment. I&apos;m just using a simple example to show you what&apos;s possible.&lt;/p&gt;
&lt;h4&gt;Using Custom Fonts via XML&lt;/h4&gt;
&lt;p&gt;Head over to your XML layout file. Let&apos;s skip the layout design and go straight to using our fonts.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;TextView
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;wrap_content&quot;
    android:fontFamily=&quot;@font/merriweather_regular&quot;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here&apos;s my simple TextView. All you need to use a font is ONE attribute, and you&apos;re good to go. Its really that easy!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;android:fontFamily=&quot;@font/merriweather_regular&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Custom Fonts via Java&lt;/h4&gt;
&lt;p&gt;You can assign a font programmatically too. First fetch the font typeface. Then set it to your &lt;code&gt;TextView&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Typeface typefaceLato = getResources().getFont(R.font.lato_regular);
mTextIntro.setTypeface(typefaceLato);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Additionally, you can even specify a basic font style such has &lt;em&gt;bold, italic&lt;/em&gt; or a combination of the two.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mTextIntro.setTypeface(typefaceLato, Typeface.BOLD_ITALIC);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./android-o-tutorial-custom-font-resources/custom_font_resources_typeface_styles.png&quot; alt=&quot;&quot; title=&quot;Custom font typeface styles&quot; /&gt;&lt;/p&gt;
&lt;p&gt;There&apos;s something interesting to note here. If you&apos;re using a font family, you&apos;ll have the same font, with different weight. You know what I&apos;m talking about. If you download a font and extract the .zip file, you&apos;ll get multiple font variations like this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-o-tutorial-custom-font-resources/font_resources_ttf_weight_variations.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So for example, assume I&apos;m using Merriweather-Regular. If Iset the typeface style to bold, Android will choose Merriweather-Bold from my font-family and display that. Now that I&apos;ve dropped a hint about font family, you might be wondering what exactly it is. So let&apos;s talk about that next.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Using a font family&lt;/h2&gt;
&lt;p&gt;As we&apos;ve seen above, what if you want to use the same font in its different styles? Alright, maybe you can get away using the default Typeface style of bold or italic. But what if you want a thinner font? Thin and italic? When you downloaded the .zip file from Google Fonts, did you notice there wasn&apos;t just a single font? There was a multitude of them. All varying in weight or thickness. You can group all these different fonts, and use them together as a font family.&lt;/p&gt;
&lt;h3&gt;Creating a Font Family&lt;/h3&gt;
&lt;p&gt;You can do this in 3 easy steps.&lt;/p&gt;
&lt;p&gt;1 Right click the &lt;em&gt;res/fonts&lt;/em&gt; folder and create a new &apos;&lt;em&gt;Font resource file&lt;/em&gt;&apos;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-o-tutorial-custom-font-resources/custom_font_new_font_resource_file.png&quot; alt=&quot;&quot; title=&quot;Create New Font resource file&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Add an element for EVERY font variation you wish to include. Let&apos;s go back to the design we&apos;re trying to do. Font styles that are thin, thick and in italics would be nice. So let&apos;s add three. I only wish to vary fonts for the body content. So let&apos;s add 3 font variations for &lt;em&gt;Lato&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;font-family xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&amp;gt;
    &amp;lt;font
        android:font=&quot;@font/lato_light&quot;
        android:fontStyle=&quot;normal&quot;
        android:fontWeight=&quot;300&quot;/&amp;gt;

    &amp;lt;font
        android:font=&quot;@font/lato_regular&quot;
        android:fontStyle=&quot;normal&quot;
        android:fontWeight=&quot;400&quot;/&amp;gt;

    &amp;lt;font
        android:font=&quot;@font/lato_bold&quot;
        android:fontStyle=&quot;normal&quot;
        android:fontWeight=&quot;700&quot;/&amp;gt;
&amp;lt;/font-family&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you&apos;re unsure about the &lt;code&gt;fontWeight&lt;/code&gt;, a quick look at Google Fonts will clear your doubts.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-o-tutorial-custom-font-resources/font_resources_google_font_download_ttf.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;After that, using a single font from a font family is the same. Just reference them via the font attribute&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;android:fontFamily=&quot;@font/lato_black&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Just remember to first add all your font variations to the font folder. Then create a &apos;&lt;em&gt;Font resource file&lt;/em&gt;&apos;. Then add an element per font variation. Finally, reference your font style just like a regular single font.&lt;/p&gt;
&lt;h4&gt;Customizing Font Styles for Readability&lt;/h4&gt;
&lt;p&gt;Using the fonts outright on a &lt;code&gt;TextView&lt;/code&gt; does not guarantee good readability. Take a look for yourselves.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-o-tutorial-custom-font-resources/custom_font_resources_no_readability-copy.png&quot; alt=&quot;&quot; title=&quot;Default TextView&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Seriously, that’s bad. It hardly readable. Keep in mind that a smartphone is a small device, compared to a desktop or tablet. This makes it harder to read the text. So if your app’s priority is for users to read content. Then its also your priority to make sure the content is easy to read. The key lies in playing around with two attributes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;letterSpacing&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lineSpacingExtra&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So with that in mind, here are my &lt;code&gt;TextView&lt;/code&gt; elements in the layout.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...
&amp;lt;TextView
    style=&quot;@style/TextAppearance.AppCompat.Headline&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;wrap_content&quot;
    android:fontFamily=&quot;@font/merriweather_regular&quot; /&amp;gt;

&amp;lt;TextView
    style=&quot;@style/TextAppearance.AppCompat.Subhead&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;wrap_content&quot;
    android:lineSpacingExtra=&quot;4dp&quot;
    android:letterSpacing=&quot;0.08&quot; /&amp;gt;

&amp;lt;TextView
    style=&quot;@style/TextAppearance.AppCompat.Body1&quot;
    android:layout_width=&quot;match_parent&quot;
    android:letterSpacing=&quot;0.04&quot;
    android:layout_height=&quot;wrap_content&quot;
    android:fontFamily=&quot;@font/lato_regular&quot;
    android:lineSpacingExtra=&quot;4dp&quot; /&amp;gt;
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With these extra attributes, font should now be easy to read. See the difference for yourself. Its better right?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-o-tutorial-custom-font-resources/font_readability_before_after.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;If you have a hard time remembering the different attributes, use the &apos;&lt;em&gt;Design&lt;/em&gt;&apos; Pane in the XML Editor. The &apos;&lt;em&gt;Properties&lt;/em&gt;&apos; pane on the right, lists all available attributes that you can change.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-o-tutorial-custom-font-resources/android_studio_textview_properties_pane-1.png&quot; alt=&quot;&quot; title=&quot;TextView Properties in Design view of XML editor&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Final Results&lt;/h2&gt;
&lt;p&gt;Here&apos;s how the app finally looks like.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-o-tutorial-custom-font-resources/custom_font_resources_op-copy.png&quot; alt=&quot;&quot; title=&quot;What we&apos;ll be creating&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now take a breather here and notice how easily this was. We used 3 different custom fonts without breaking a sweat. Using a font of your choice is as simple as drag and drop! Then, all it took was a single attribute to reference the font file. I&apos;ve used &lt;code&gt;merriweather_regular&lt;/code&gt; for the large title heading. The following introduction text is like a quote. That uses &lt;code&gt;lato_bold&lt;/code&gt;, with &lt;code&gt;Typeface.ITALIC&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Typeface typefaceLato = getResources().getFont(R.font.lato_bold);
mTextIntro.setTypeface(typefaceLato, Typeface.ITALIC);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yes, such a mix and match is also possible.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SOURCE CODE:&lt;/strong&gt; &lt;a href=&quot;https://github.com/Suleiman19/Android-O-Sample/blob/master/app/src/main/java/com/iamsuleiman/androido/FontActivity.java&quot;&gt;Available on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Where to from here?&lt;/h3&gt;
&lt;p&gt;Using custom Font resources is just one of the new features in Android O. You can &lt;a href=&quot;https://blog.iamsuleiman.com/android-o-what-developers-need-know/&quot;&gt;read about the other Android O features here&lt;/a&gt;. While using custom fonts is something basic, its good to know its finally added. Also, it&apos;s relative ease of use makes this feature adoptable by many Android Developers. So what&apos;s your take on custom fonts? How are you using it? Let me know in the comments. Also, I&apos;ll be covering other new Android O tutorials in future articles. So don&apos;t forget to subscribe below.&lt;/p&gt;
</content:encoded></item><item><title>Android O Preview: What Developers Need to Know</title><link>https://blog.iamsuleiman.com/android-o-what-developers-need-know/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/android-o-what-developers-need-know/</guid><description>The Android O SDK (API 26) dropped recently and the internet went nuts! The Developer Preview SDKs brought along many new features. But these new SDKs</description><pubDate>Wed, 29 Mar 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The Android O SDK (API 26) dropped recently and the internet went nuts! The Developer Preview SDKs brought along many new features. But these new SDKs are the pre-final ones. It&apos;s that time of the year when Android Developers like you and me need to keep up with what&apos;s latest. I usually refrain from writing about Developer Previews, until a stable release arrives. But it&apos;s better we get to know what&apos;s new now. Rather than coping with changes in the future. So transitioning our apps to Android O will be smooth when the time comes.&lt;/p&gt;
&lt;h2&gt;Trying Android O with Android Studio EAP&lt;/h2&gt;
&lt;p&gt;Android Studio EAP (Canary Channel)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Credits: &lt;a href=&quot;http://tools.android.com&quot;&gt;tools.android.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In this post, we&apos;ll first see how to setup &lt;strong&gt;Android Studio Preview&lt;/strong&gt;. We need this to try out the new Android O Developer Preview SDKs. Google I/O 2017 released Android Studio 3.0. They also released Android O RC2. Hence this updated article will be using them. But don’t worry as I’ll walk you through that as well. We’ll install Android Studio EAP in parallel to your existing Android Studio. So nothing will get affected. Next, we&apos;ll install the Android O Preview SDKs. This includes the Preview SDKs itself, Support Libraries and a System Image.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-o-what-developers-need-know/o-preview-updates.svg&quot; alt=&quot;&quot; title=&quot;Android O release schedule. Credits: developer.android.com&quot; /&gt;&lt;/p&gt;
&lt;p&gt;As you can see from the release schedule. We no longer have to use the preview SDKs. The beta SDKs for API 26 (Android O) has been released. We will be using that from now on. Before setting up everything, let&apos;s see what Android O has to offer.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Some of the biggest features in Android O are:&lt;/p&gt;
&lt;h3&gt;1. Picture-in-Picture (PIP) support for Android Mobile&lt;/h3&gt;
&lt;p&gt;PIP was first introduced in Android Nougat. It became famous by the floating video player in YouTube. Just add the attribute &lt;code&gt;android:supportsPictureInPicture&lt;/code&gt; attribute in your tag in &lt;em&gt;AndroidManifest.xml&lt;/em&gt;. But, back then it was limited to Android TV. With Android O, they&apos;ve finally brought it to smartphones as well. Goodbye &lt;a href=&quot;https://github.com/pedrovgs/DraggablePanel&quot;&gt;&lt;code&gt;DraggablePanel&lt;/code&gt;&lt;/a&gt;?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/android-o-what-developers-need-know/youtube-picture-in-picture-pip.gif&quot; alt=&quot;&quot; title=&quot;PIP in YouTube app&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Learn how to &lt;a href=&quot;https://blog.iamsuleiman.com/android-o-tutorial-picture-in-picture-pip/&quot;&gt;use Picture-in-Picture in this Android O tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;2. Custom Font support&lt;/h3&gt;
&lt;p&gt;No need to use a library or write a custom View. Drop in your fonts to &lt;em&gt;res/fonts&lt;/em&gt; folder. Then you can use them with a single attribute.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;android:fontFamily=&quot;@font/Merriweather&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally we can start seeing apps with less of Roboto! You can read the full &lt;a href=&quot;https://blog.iamsuleiman.com/android-o-tutorial-custom-font-resources/&quot;&gt;tutorial on how to use custom font resources&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;3. Autofill Framework&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Users can save time filling out forms by using autofill in their devices&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Long story short. Are you familiar with auto-filling forms in your web browsers? Remembering your passwords and credit card information to autofill it when required. That’s available on Android now. Sweet?&lt;/p&gt;
&lt;h3&gt;4. Notification Channels&lt;/h3&gt;
&lt;p&gt;Notifications are great. Every Android release made it better. But honestly, notifications are a spam-fest on our phones right now.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Notification Channels provide a unified system to help users manage notifications&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In short, Notification Channels let you group your notification into broad categories. You can change the behavior of these broad notification categories in your settings.&lt;/p&gt;
&lt;h3&gt;Other little, but noteworthy changes&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Adaptive Icons&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Adaptive icons can help you integrate better with device UI, which can display a variety of shapes across different device models.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Honestly, I don&apos;t get the point of this feature. It started with Nougat wanting to make every icon round. But now this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/android-o-what-developers-need-know/NB_Icon_Mask_Shapes_Ext_02.gif&quot; alt=&quot;&quot; title=&quot;Credits to android-developers.googleblog.com&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ProgressDialog deprecated&lt;/strong&gt; &lt;a href=&quot;https://developer.android.com/reference/android/app/ProgressDialog.html&quot;&gt;Developer docs&lt;/a&gt; suggest a good UX tip. To use an inline ProgressBar in an Activity, instead of this modal dialog. But, you can take it a step further by &lt;a href=&quot;https://blog.iamsuleiman.com/stop-using-loading-spinner-theres-something-better/&quot;&gt;using a better Progress Indicator called Skeleton Screen&lt;/a&gt;. &lt;strong&gt;Text Justification&lt;/strong&gt; Spreads the typography over the full width. You just need one line and you&apos;re good to go.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;textView.setJustify(true);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Directional Attributes&lt;/strong&gt; No more padding top, bottom, left and right. Just paddingHorizontal and paddingVertical. Save yourself from writing two extra lines.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-o-what-developers-need-know/C7g-OfdX0AAtbFp.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Credits to &lt;a href=&quot;https://twitter.com/cyrilmottier/status/844493353135853568/photo/1&quot;&gt;Cryil Mottier&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;for this&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;OpenJDK Features for Android O&lt;/strong&gt; Some of the newly added packages include &lt;code&gt;java.time&lt;/code&gt; and &lt;code&gt;java.nio.file&lt;/code&gt;. You can read the complete &lt;a href=&quot;https://developer.android.com/sdk/api_diff/o-dp1/changes.html&quot;&gt;Android O API differences report here&lt;/a&gt;. &lt;strong&gt;Smart Sharing&lt;/strong&gt; Android O learns your preference and suggests relevant apps depending on what you’re sharing. For example, if you want to share a photo, Android might suggest social media apps. Now we&apos;re fully aware of what Android O has to offer. Time for us Android Developers to start preparing our apps for Android O.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;How to Develop for Android O right now?&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;To access the preview, you must first download to Android Studio 3.0 Preview.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;A word of caution:&lt;/strong&gt; Keep in mind, we&apos;re using an unstable IDE. So make sure to update your SDKs and IDE as soon as an update is available. The &lt;a href=&quot;https://developer.android.com/studio/preview/install-preview.html&quot;&gt;official Android developer documentation&lt;/a&gt; explains how to setup Android O. I highly recommend you follow their guide first. You can safely install Android Studio Preview in parallel to your existing, stable Android Studio. In short, nothing gets affected. Android Studio Preview will safely use your existing SDK path. &lt;strong&gt;NOTE:&lt;/strong&gt; As of now, you must use Android Studio preview. Otherwise many of the new features simply will not work!&lt;/p&gt;
&lt;h3&gt;Android O SDK Download&lt;/h3&gt;
&lt;p&gt;Open SDK Manager and download the Android O SDK (API 26). Notice that these are the almost-final SDKs that you can expect in production. In other words, these include API changes that will carry forward from now on.&lt;/p&gt;
&lt;h4&gt;Android O DP2 Install Checklist&lt;/h4&gt;
&lt;p&gt;But just in case, here&apos;s a quick checklist of everything you need to do:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download and install &lt;a href=&quot;https://developer.android.com/studio/preview/index.html&quot;&gt;Android Studio 3.0 Preview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Next, install &lt;strong&gt;Android 7+ (O) - SDK Platform 26&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Download a preview image for emulator (&lt;em&gt;Google Play Intel x86 Atom System Image&lt;/em&gt;). This includes Google Play Services&lt;/li&gt;
&lt;li&gt;Download and install &lt;em&gt;SDK Build-Tools 26&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Update your SDK Tools(26.0.2) and SDK Platform-Tools (26.0.0)&lt;/li&gt;
&lt;li&gt;Create a new project targeting Android O Preview&lt;/li&gt;
&lt;li&gt;Check &lt;em&gt;app/build.gradle&lt;/em&gt; if correct &lt;em&gt;targetSdkVersion&lt;/em&gt; and Support libraries are used&lt;/li&gt;
&lt;li&gt;Create a new AVD targeting Android O&lt;/li&gt;
&lt;li&gt;Test your app by running it on the new AVD&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The setup might look exhausting. But trust me, it took hardly an hour to do all that. Once you&apos;re done with all that, you&apos;ll need to update your Gradle plugin as well. So first, replace the &lt;code&gt;**distributionUrl**&lt;/code&gt; in your &lt;strong&gt;&lt;em&gt;gradle-wrapper.properties&lt;/em&gt;&lt;/strong&gt; file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;distributionUrl=https\\://services.gradle.org/distributions/gradle-4.0-rc-1-all.zip
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This gives you the latest Gradle version that you need to be using for API 26. Otherwise your project will fail to compile. Finally, cross-check your &lt;em&gt;&lt;strong&gt;app/build.gradle&lt;/strong&gt;&lt;/em&gt; file with mine.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apply plugin: &apos;com.android.application&apos;

android {
    compileSdkVersion 26
    buildToolsVersion &quot;26.0.0&quot;
    defaultConfig {
        applicationId &quot;com.iamsuleiman.androido&quot;
        minSdkVersion 14
        targetSdkVersion 26
        versionCode 1
        versionName &quot;1.0&quot;
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile(&apos;proguard-android.txt&apos;), &apos;proguard-rules.pro&apos;
        }
    }
    // To take advantage of cool Java 8 features, like Lambdas!
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

ext {
    supportLibVersion = &quot;26.0.0-beta2&quot;
}

dependencies {
    compile fileTree(dir: &apos;libs&apos;, include: \[&apos;\*.jar&apos;\])
    ...
    compile &quot;com.android.support:appcompat-v7:${supportLibVersion}&quot;
    compile &quot;com.android.support:design:${supportLibVersion}&quot;
    compile &quot;com.android.support:recyclerview-v7:${supportLibVersion}&quot;
    ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you&apos;re gradle file is looking like this, then you&apos;re all set to play with Android O. Moreover, &lt;em&gt;&lt;a href=&quot;http://developer.android.com&quot;&gt;developer.android.com&lt;/a&gt;&lt;/em&gt; does a good job of walking you through. It is fairly simple. But, if you get stuck anywhere, feel free to drop a comment here or &lt;a href=&quot;https://ctt.ec/g0ARr&quot;&gt;send me a Tweet&lt;/a&gt;. I’ll be happy to help.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;What’s next?&lt;/h2&gt;
&lt;p&gt;With Android Studio 3.0 Preview setup, and the new SDKs downloaded, you’re good to go. You can compile and test your apps against Android O and check if everything works smoothly. Also, you can use this time to make your apps take advantages of the new features. For example, expect the Autofill Framework and Notification Channels to be widely used. Even if you don’t want to support Android O right now, it&apos;s okay. You can test drive the new SDKs and see what it has to offer. So what did you like about Android O? Did you notice the new changes from the previous release? My particular favourite is &lt;a href=&quot;https://blog.iamsuleiman.com/android-o-tutorial-custom-font-resources/&quot;&gt;downloadable custom fonts&lt;/a&gt;. What’s your favourite feature? Did I miss anything? Tell me in the comments below.&lt;/p&gt;
</content:encoded></item><item><title>Introduction to Google&apos;s Awareness API</title><link>https://blog.iamsuleiman.com/introduction-googles-awareness-api/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/introduction-googles-awareness-api/</guid><description>A while ago, Google announced something really interesting called the Awareness API. According to Google Developers(https://developers.google.com/) - </description><pubDate>Tue, 14 Mar 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A while ago, Google announced something really interesting called the Awareness API. According to &lt;a href=&quot;https://developers.google.com/&quot;&gt;Google Developers&lt;/a&gt; -  Android Awareness API bridges the physical world of users, and the digital world of Android to help you build more assistive and context-aware apps.&lt;/p&gt;
&lt;p&gt;The last sentence can be a bit confusing. So here are some examples that will help you realise how powerful the Awareness API is:&lt;/p&gt;
&lt;p&gt;Imagine you pass by a pharmacy and your phone reminds you that you have to buy medicines. Or as soon you enter your car, your phone automatically connects to the car&apos;s Bluetooth and your navigation app opens up in driver mode. Cool right? Awareness API makes this really easy.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Credits: Google&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;What does the Awareness API mean for us?&lt;/h2&gt;
&lt;p&gt;The Awareness API unifies 7 location and context signals in a single API.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Context is at the heart of the Awareness API&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let&apos;s take a quick look at the 7 context types offered by the Awareness API.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;#time&quot;&gt;Time&lt;/a&gt;:&lt;/strong&gt; Current local time&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;#location&quot;&gt;Location&lt;/a&gt;:&lt;/strong&gt; Latitude and longitude&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;#places&quot;&gt;Place&lt;/a&gt;:&lt;/strong&gt; Place, including place type&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;#activity&quot;&gt;Activity&lt;/a&gt;:&lt;/strong&gt; Detected user activity (walking, running, biking)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;#beacons&quot;&gt;Beacons&lt;/a&gt;:&lt;/strong&gt; Nearby beacons matching the specified namespace&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;#headphones&quot;&gt;Headphones&lt;/a&gt;:&lt;/strong&gt; Are headphones plugged in?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;#weather&quot;&gt;Weather&lt;/a&gt;:&lt;/strong&gt; Current weather conditions&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Why use the Awareness API?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;One API to rule them all&lt;/strong&gt; You just need to add a single API and you are set. No headache of using tonnes of different APIs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Battery and Data Friendly&lt;/strong&gt; The API takes care of managing your battery life and data usage so that you can concentrate on features crucial to your app.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Better context data&lt;/strong&gt; Raw signals are processed for improved quality. For example, advanced algorithms are used to determine the user&apos;s activity with a high level of accuracy.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Set up&lt;/h2&gt;
&lt;p&gt;Awareness API is a part of Google Play Services and was introduced in v9.2. Let&apos;s configure our project to use the Awareness API. Create a project on &lt;a href=&quot;https://console.developers.google.com/&quot;&gt;Google Developer Console&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./introduction-googles-awareness-api/console.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Go to the &lt;a href=&quot;https://console.developers.google.com/apis/library&quot;&gt;APIs Library&lt;/a&gt; and search for Awareness API. Then click on it and &lt;strong&gt;Enable&lt;/strong&gt; it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./introduction-googles-awareness-api/api-library-awareness-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Next, go to Credentials &amp;gt; Create Credentials &amp;gt; API Key &amp;gt; Android Key. Enter the name of your project and click create. You will now be given an API key.  Copy it down somewhere. Next, in your Android Studio project, add the following dependency in  &lt;em&gt;app/&lt;/em&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;em&gt;build.gradle&lt;/em&gt;.&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dependencies {
    ...
    compile &apos;com.google.android.gms:play-services-awareness:10.2.0&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Add the following code to the &lt;code&gt;&amp;lt;application/&amp;gt;&lt;/code&gt; tag of your &lt;em&gt;AndroidManifest.xml&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Remember to replace &quot;&lt;em&gt;YOUR_KEY&lt;/em&gt;&quot; with the API Key you obtained. That&apos;s it! You are now ready to use the awesome Awareness API.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Fences and Snapshots&lt;/h3&gt;
&lt;p&gt;The Awareness API provides two distinct APIs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Fences&lt;/strong&gt;: Helps detect changes in user&apos;s context, or when certain context conditions are met. For example, show a notification when the user reaches a certain location. Or even when the user starts walking or running.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Snapshot&lt;/strong&gt;: Let&apos;s your app request information related to the user&apos;s current context. For example, what activity the user is currently engaged in.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In short, the Snapshot API helps you detect and identify changes in environment. Whereas the Fences API helps you react to those changes. In this post, lets keep things simple and go through the Snapshots API alone. We&apos;ll talk about the Fences API in the next post.&lt;/p&gt;
&lt;h3&gt;Snapshot API&lt;/h3&gt;
&lt;p&gt;Remember the 7 context types we discussed early? It&apos;s time to dive into some code now.&lt;/p&gt;
&lt;h4&gt;1. Time&lt;/h4&gt;
&lt;p&gt;We can get the local time by using Android&apos;s Time API. Hence there is no separate function for Time in the Awareness API. But since we are diving into code, here&apos;s how you can get the locale time.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
Log.d(TAG, dateFormat.format(date));
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2. Location&lt;/h4&gt;
&lt;p&gt;Get the user&apos;s coordinates. Since we are dealing with locations, we will need to make sure our app has Location permission.  Here is a quick recap on how to &lt;a href=&quot;https://blog.iamsuleiman.com/runtime-permissions-android-marshmallow/&quot;&gt;handle runtime permissions on Android Marshmallow and above&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Awareness.SnapshotApi
		.getLocation(googleApiClient)
       .setResultCallback(new ResultCallback() {
           @Override
           public void onResult(@NonNull LocationResult locationResult) {
               if (!locationResult.getStatus().isSuccess()) {
                   Log.e(TAG, &quot;Unable to get location&quot;);
                   return;
               }
               Location location = locationResult.getLocation();
               Log.i(TAG, &quot;Latitude: &quot; + location.getLatitude() );
               Log.i(TAG, &quot;Longitude: &quot; + location.getLongitude() );
           }
       });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;getLocation()&lt;/code&gt; method has a callback that returns a &lt;code&gt;LocationResult&lt;/code&gt; object. Then, we can use the LocationResult object to get the user&apos;s latitude and longitude. For that, we use the methods &lt;code&gt;getLatitude()&lt;/code&gt; and &lt;code&gt;getLongitude()&lt;/code&gt;.&lt;/p&gt;
&lt;h4&gt;3. Places&lt;/h4&gt;
&lt;p&gt;Get places around user&apos;s location. The following example shows getting a list of possible places:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Awareness.SnapshotApi.getPlaces(mGoogleApiClient)
             .setResultCallback(new ResultCallback() {
                 @Override
                 public void onResult(@NonNull PlacesResult placesResult) {
                     if (!placesResult.getStatus().isSuccess()) {
                         Log.e(TAG, &quot;Could not get places.&quot;);
                         return;
                     }
                     List placeLikelihoodList = placesResult.getPlaceLikelihoods();
                     // Show the top 5 possible location results.
                     for (int i = 0; i &amp;lt; 5; i++) {
                         PlaceLikelihood p = placeLikelihoodList.get(i);
                         Log.i(TAG, p.getPlace().getName().toString() + &quot;, likelihood: &quot; + p.getLikelihood());
                     }
                 }
             });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To use the &lt;code&gt;SnapshotAPI.getPlcaes()&lt;/code&gt; method, you must:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Enable the Google Places API for Android in your &lt;a href=&quot;https://console.developers.google.com&quot;&gt;Google Developers Console&lt;/a&gt; project.&lt;/li&gt;
&lt;li&gt;Add the &lt;code&gt;android.permission.ACCESS_FINE_LOCATION&lt;/code&gt; permission to &lt;em&gt;AndroidManifest.xml&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In case you are developing for Android Marshmallow and above, make sure to handle the runtime permission for location.&lt;/p&gt;
&lt;h4&gt;4. Activity&lt;/h4&gt;
&lt;p&gt;Get the activity the user is currently busy in by using the &lt;code&gt;getDetectedActivity()&lt;/code&gt; method. The &lt;code&gt;getDetectedActivity()&lt;/code&gt; method requires  &lt;code&gt;com.google.android.gms.permission.ACTIVITY_RECOGNITION&lt;/code&gt; permission. Add this permission to  &lt;code&gt;AndroidManifest.xml&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Awareness.SnapshotApi.getDetectedActivity(mGoogleApiClient)
        .setResultCallback(new ResultCallback() {
            @Override
            public void onResult(@NonNull DetectedActivityResult detectedActivityResult) {
                if (!detectedActivityResult.getStatus().isSuccess()) {
                    Log.e(TAG, &quot;Could not get the current activity.&quot;);
                    return;
                }
                ActivityRecognitionResult ar = detectedActivityResult.getActivityRecognitionResult();
                DetectedActivity probableActivity = ar.getMostProbableActivity();
                Log.i(TAG, probableActivity.toString());
            }
        });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;DetectedActivityResult.getActivityRecognitionResult()&lt;/code&gt; returns an &lt;code&gt;ActivityRecognitionResult&lt;/code&gt;. We can use the following functions to get various data related to the user&apos;s activity&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getMostProbableActivity()&lt;/code&gt; to get only the most probable activity&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hasResult()&lt;/code&gt; to detect whether an &lt;code&gt;Intent&lt;/code&gt; contains an &lt;code&gt;ActivityRecognitionResult&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getActivityConfidence()&lt;/code&gt; to return the confidence value for a given activity type.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getProbableActivities()&lt;/code&gt; to get a list of recent activities ranked by probability.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;5. Weather&lt;/h4&gt;
&lt;p&gt;We can use &lt;code&gt;SnapshotApi.getWeather()&lt;/code&gt; to get the weather conditions of the user&apos;s current location. The SnapshotApi.getWeather() method requires the  &lt;code&gt;android.permission.ACCESS_FINE_LOCATION&lt;/code&gt; permission. Add this permission to &lt;code&gt;AndroidManifest.xml&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Awareness.SnapshotApi.getWeather(mGoogleApiClient)
                .setResultCallback(new ResultCallback() {
                    @Override
                    public void onResult(@NonNull WeatherResult weatherResult) {
                        if (!weatherResult.getStatus().isSuccess()) {
                            Log.e(TAG, &quot;Could not get weather.&quot;);
                            return;
                        }
                        Weather weather = weatherResult.getWeather();
                        Log.i(TAG, &quot;Weather: &quot; + weather);
                    }
                });
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;6. Headphone&lt;/h4&gt;
&lt;p&gt;We can use &lt;code&gt;SnapshotApi.getHeadphoneState()&lt;/code&gt; to detect whether headphones are plugged into the device or not. It returns a &lt;code&gt;HeadphoneStateResult&lt;/code&gt;. We can then call &lt;code&gt;HeadphoneStateResult.getHeadphoneState()&lt;/code&gt; to get the headphone status.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Awareness.SnapshotApi.getHeadphoneState(mGoogleApiClient)
                .setResultCallback(new ResultCallback() {
                    @Override
                    public void onResult(@NonNull HeadphoneStateResult headphoneStateResult) {
                        if (!headphoneStateResult.getStatus().isSuccess()) {
                            Log.e(TAG, &quot;Could not get headphone state.&quot;);
                            return;
                        }
                        HeadphoneState headphoneState = headphoneStateResult.getHeadphoneState();
                        if (headphoneState.getState() == HeadphoneState.PLUGGED_IN) {
                            Log.i(TAG, &quot;Headphones are plugged in.\n&quot;);
                        } else {
                            Log.i(TAG, &quot;Headphones are NOT plugged in.\n&quot;);
                        }
                    }
                });
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;7. Beacons&lt;/h4&gt;
&lt;p&gt;We can use &lt;code&gt;getBeaconState()&lt;/code&gt; to get information about nearby beacons. To use the &lt;code&gt;getBeaconState()&lt;/code&gt; method, we need to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Add &lt;code&gt;android.permission.ACCESS_FINE_LOCATION&lt;/code&gt; to &lt;em&gt;AndroidManifest.xml&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Activate the &apos;Nearby Messages API&apos; for the &lt;a href=&quot;http://console.developers.google.com&quot;&gt;Google Developers Console&lt;/a&gt; project.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We need to declare all the possible attachment&apos;s namespaces and types in a &lt;strong&gt;&lt;code&gt;TypeFilter&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private static final List BEACON_TYPE_FILTERS = Arrays.asList(
        BeaconState.TypeFilter.with(
                &quot;my.beacon.namespace&quot;,
                &quot;my-attachment-type&quot;),
        BeaconState.TypeFilter.with(
                &quot;my.other.namespace&quot;,
                &quot;my-attachment-type&quot;));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If your beacon&apos;s attachment &lt;strong&gt;namespaceType&lt;/strong&gt; is &lt;code&gt;my-sample-project/mydata&lt;/code&gt; , my.beacon.namespace would be &lt;strong&gt;my-sample-project&lt;/strong&gt; while my-attachment-type would be &lt;strong&gt;mydata&lt;/strong&gt;. Then, we can get the state of the beacon using the following code.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Awareness.SnapshotApi.getBeaconState(mGoogleApiClient, BEACON_TYPE_FILTERS)
                .setResultCallback(new ResultCallback() {
                    @Override
                    public void onResult(@NonNull BeaconStateResult beaconStateResult) {
                        if (!beaconStateResult.getStatus().isSuccess()) {
                            Log.e(TAG, &quot;Could not get beacon state.&quot;);
                            return;
                        }
                        BeaconState beaconState = beaconStateResult.getBeaconState();
                        // Get info from the BeaconState.
                    }
                });
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;Wrap up&lt;/h2&gt;
&lt;p&gt;In this post, we learnt about the Awareness API and its advantages. We also took a dive into the various context types provided by the Snapshots API. We even looked into some sample code to use each Context Type. In the next post, we will learn about the Fences API while building a nice sample app. So what are your thoughts on the Awareness API? Will you use it anytime soon? I would love to hear from you in the comments.   Header image credits: &lt;a href=&quot;https://developers.google.com/awareness/&quot;&gt;Google Awareness API&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Stop Using Loading Spinner, There’s Something Better</title><link>https://blog.iamsuleiman.com/stop-using-loading-spinner-theres-something-better/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/stop-using-loading-spinner-theres-something-better/</guid><description>Stop using those boring loading spinners in your user interfaces. Seriously. It&apos;s killing your apps&apos; experience more than you know. A loading spinner </description><pubDate>Tue, 28 Feb 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Stop using those boring loading spinners in your user interfaces. Seriously. It&apos;s killing your apps&apos; experience more than you know.&lt;/p&gt;
&lt;p&gt;A loading spinner might be the solution to your content loading problems. But I’m here to tell you that it&apos;s not.&lt;/p&gt;
&lt;p&gt;You might even use some of those fancy animated loading Spinners. But they’re not any better either.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/stop-using-loading-spinner-theres-something-better/spinkit6.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://dribbble.com/shots/2371491-Folding-cube-spinner-CSS&quot;&gt;By Tobias Ahlin on Dribbble&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Why Loading Spinner doesn’t work&lt;/h2&gt;
&lt;p&gt;From a long time we’re following, or rather influenced by hard rules from design languages. I don’t blame you, though.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The key to wisdom is this - constant and frequent questioning, for by doubting we are led to question and by questioning we arrive at the truth. - Peter Abelard&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Loading Spinner is one of the most used progress indicators in user interface design. But it has its own flaws which are generally overlooked.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./stop-using-loading-spinner-theres-something-better/facebook_loading_spinner_overload.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Facebook using Loading Spinners for image and Pagination&lt;/p&gt;
&lt;p&gt;After staring at too many Loading Spinners&lt;/p&gt;
&lt;h3&gt;No sign of progress&lt;/h3&gt;
&lt;p&gt;What does the loading spinner tell you? It denotes that content is currently loading. But does it say how much has loaded? Does it say how much remains to load?&lt;/p&gt;
&lt;p&gt;No, it doesn’t.&lt;/p&gt;
&lt;p&gt;Moreover, it&apos;s difficult to determine. If it could, we’d be using a progress bar right?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;That period of uncertainty&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/stop-using-loading-spinner-theres-something-better/inkling_spinner.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://dribbble.com/shots/1201310-Animated-Loading-Spinner&quot;&gt;By Chanpory Rith on Dribbble&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;How long did you spend looking at that? Were you expecting some content to load after some time? I’m sorry to disappoint.&lt;/p&gt;
&lt;p&gt;Ok, let’s assume that GIF loading actually completed and some content displays. Ask yourselves these questions and give me an honest response. I’m sure you’ve stared at enough Loading Spinners to know.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;When you looked at the Loading Spinner, did you know how much time remains to complete?&lt;/li&gt;
&lt;li&gt;How much of the content has loaded?&lt;/li&gt;
&lt;li&gt;How much remains to load?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We simply sit staring at a Loading Spinner. Hoping that it loads in time, with no answer to either of those 3 questions.&lt;/p&gt;
&lt;p&gt;Moreover, network connections might be unstable. So we can never take for granted that content will always load fast.&lt;/p&gt;
&lt;h3&gt;Perceived to be slower than actual&lt;/h3&gt;
&lt;p&gt;Loading Spinners make loading appear slower.&lt;/p&gt;
&lt;p&gt;It&apos;s like a clock, constantly ticking. It shows the time you’re wasting by staring at it. Like that GIF above, which I made you stare at.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://gph.is/1MoI2wJ&quot;&gt;http://gph.is/1MoI2wJ&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;What comes next is a surprise&lt;/h3&gt;
&lt;p&gt;Until everything has loaded, do you have any idea what to expect on screen? I bet you don’t. You might even get surprised once the UI and content display.&lt;/p&gt;
&lt;p&gt;Now think about your users. Until everything has loaded, they have completely no idea what to expect on screen. I bet they’ll get surprised too.&lt;/p&gt;
&lt;p&gt;This won’t be their fault. You didn’t tell them what to expect in the first place!&lt;/p&gt;
&lt;h4&gt;A ‘Surprise’ isn’t always a good thing&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;An unexpected or astonishing event, fact, etc. - Surprise&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;From the very definition of the word, a surprise indicates an ’&lt;em&gt;unexpected&lt;/em&gt;’ event. People tend to have polarizing reactions to such events. This could either positive or negative.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./stop-using-loading-spinner-theres-something-better/surprised-cat-meme.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Surprises don’t often tend to leave a positive impact on people. Unless it&apos;s their birthday. It depends upon how a person takes it. Thus, herein lies the problem.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./stop-using-loading-spinner-theres-something-better/app_loading.png&quot; alt=&quot;app spinner loading&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Before&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./stop-using-loading-spinner-theres-something-better/app_content_loaded.png&quot; alt=&quot;loading spinner app content loaded&quot; /&gt;&lt;/p&gt;
&lt;p&gt;After&lt;/p&gt;
&lt;p&gt;Take a good look at both the images. See the image on the right. Could you honestly predict the UI would finally look like that? I’m sure not.&lt;/p&gt;
&lt;p&gt;Alright, the final UI is a low fidelity design. But you get the point.&lt;/p&gt;
&lt;p&gt;I deliberately did not pull examples from existing apps. Because you and I both know what it will look like. With a known app, we’ve already seen the interface, even before its loaded.&lt;/p&gt;
&lt;h3&gt;Emotions affect our sense of time&lt;/h3&gt;
&lt;p&gt;Did you know? We humans can actually predict time. That too quite accurately.&lt;/p&gt;
&lt;p&gt;But under an emotional influence, our sense of time is significantly clouded.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://gph.is/1XcuFKh&quot;&gt;http://gph.is/1XcuFKh&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We’ve all experienced this. Time seems to fly when you’re doing what you love. But if it&apos;s something you hate, time seems to drag. Even when you’re bored, staring at the clock waiting for your favorite show. Time moves even slower then.&lt;/p&gt;
&lt;p&gt;The same holds true for our interfaces.&lt;/p&gt;
&lt;p&gt;The point I’m trying to make is. Your content might not take much time to load. In fact, it might not be a big deal. But it may appear longer than it actually takes. It is just how people might perceive it, and there’s nothing we can do to change it.&lt;/p&gt;
&lt;p&gt;But what we can do, is help change their perception. We can make our app appear faster than it actually is.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
Don’t get too carried away trying to fake it. Your interface needs a combination of real and perceived speed to succeed.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;The Illusion of Alternatives&lt;/h3&gt;
&lt;p&gt;Typically, we have two options to denote loading content:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Finite progress bar&lt;/strong&gt; - if we can determine load times&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Loading Spinner&lt;/strong&gt; (infinite loading progress) - if load times are unknown&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;But take a closer look at the choices again. Do you realise, there is no &lt;em&gt;real&lt;/em&gt; choice here?&lt;/p&gt;
&lt;p&gt;We can&apos;t use a finite progress bar because we cannot measure load times. Also, we already know that the Loading Spinner is no good.&lt;/p&gt;
&lt;h4&gt;A good progress indicator&lt;/h4&gt;
&lt;p&gt;A good progress indicator is one which obviously doesn’t have any of the negatives I mentioned above. But for a more optimistic tone, let me list them out.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;gives immediate feedback&lt;/li&gt;
&lt;li&gt;provides a sense of time ( how much has progressed, and how much is pending)&lt;/li&gt;
&lt;li&gt;removes doubt (gradual progress reassures people that the app is working)&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;Some proof as backup&lt;/h5&gt;
&lt;p&gt;Some of you might not believe what I said. But trust me. If I was me, I wouldn’t believe what I said either. After all, where is the proof? Do loading indicators really harm? Who has experienced it?&lt;/p&gt;
&lt;p&gt;Well, then consider yourself lucky. You get to learn from someone else’s mistakes. The &lt;a href=&quot;http://www.lukew.com/ff/entry.asp?1797&quot;&gt;iOS app Polar strongly suggests avoiding the Spinner&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./stop-using-loading-spinner-theres-something-better/polar-app-ios-techcrunch.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Image credits: &lt;a href=&quot;https://techcrunch.com/2013/04/16/polars-sticky-polling-app-gets-stickier-with-its-latest-update-closes-in-on-8m-total-votes/&quot;&gt;TechCrunch&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Polar&lt;/em&gt; received a lot of complaints about their app being slow. This was because of the loading spinners they included in their app.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;With progress indicators, we had made people watch the clock. As a result, time went slower and so did our app. We focused on the indicator and not the progress, that is making it clear you are advancing toward your goal not just waiting around.&lt;br /&gt;
– &lt;em&gt;Polar&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I guess I’ve rambled enough about why Loading Spinners are bad. The problem with Spinner lies in not providing a sense of progress. Though, we can remedy this.&lt;/p&gt;
&lt;p&gt;How, you ask? The answer is &apos;&lt;em&gt;Skeleton Screens&lt;/em&gt;&apos;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;strong&gt;Skeleton Screens&lt;/strong&gt; to the rescue&lt;/h2&gt;
&lt;p&gt;Unlike Loading Spinners, where the UI displays all at once. A skeleton screen helps load a user interface gradually, a little at a time.&lt;/p&gt;
&lt;p&gt;This means that the barebones UI displays first. Then the loaded content is gradually populated on-screen.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“A skeleton screen is essentially a blank version of a page into which information is gradually loaded.”&lt;br /&gt;
– Luke Wroblewski&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./stop-using-loading-spinner-theres-something-better/linkedin-skeleton-screen-loading.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;LinkedIn recently started using Skeleton Screens for loading&lt;/p&gt;
&lt;p&gt;Skeleton screens shift the attention of users. It makes people focus on the progress, rather than the wait time.&lt;/p&gt;
&lt;p&gt;Skeleton screens visually tells users what to expect from the interface. It gives them a heads up on what&apos;s going to come and creates a sense of gradual progress.&lt;/p&gt;
&lt;p&gt;Most of all, it makes people perceive your site to be faster than it actually is. Remember that we are designing interfaces for use by real people. We need to give people the illusion of speed.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The more the system gives information about the waiting time the better the satisfaction of the user.&lt;br /&gt;
– &lt;a href=&quot;http://www.guillaumegronier.com/cv/resources/Articles/2013_WorkshopHCI_Gronier.pdf&quot;&gt;How to Improve Perceived Waiting Time in HCI&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Using a skeleton screen gives you the following benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Helps people perceive your screen to load faster&lt;/li&gt;
&lt;li&gt;Eliminates surprises&lt;/li&gt;
&lt;li&gt;Gradual loading of UI - clear indication of progress&lt;/li&gt;
&lt;li&gt;Shows exactly what&apos;s loaded and what’s yet to load&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Gradual Progression&lt;/h3&gt;
&lt;p&gt;I know it&apos;s a fancy term. What it means is, loading your content gradually. Folks from web design and development know this as ‘Lazy-loading’.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Defer initialization of an object until the point at which it is needed.&lt;br /&gt;
– &lt;a href=&quot;https://en.wikipedia.org/wiki/Lazy_loading&quot;&gt;Lazy Loading&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;First, lay out the bare bones UI (Skeleton screen). Next load the text data. The user knows they’ve received the content. Finally lazy load the images. The user understands that most of the content has loaded. What’s left are the images.&lt;/p&gt;
&lt;p&gt;In this way, you’ve given users:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a clear sense of progress&lt;/li&gt;
&lt;li&gt;what to expect next&lt;/li&gt;
&lt;li&gt;what’s left to expect&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Notice how Instagram intelligently handles loading here.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./stop-using-loading-spinner-theres-something-better/instagram-loading-gradual-progression.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Instagram loading - gradual progression&lt;/p&gt;
&lt;p&gt;First, Instagram shows a loading spinner for a brief period. Next, it lays out the barebones UI. This is the skeleton screen or Placeholder UI. This indicates the place will content will eventually fill.&lt;/p&gt;
&lt;p&gt;Also, notice that the text data has already populated the screen. Finally, in the third screenshot, the images are gradually loaded into place.&lt;/p&gt;
&lt;p&gt;Here are some websites that use skeleton screens to show loading.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./stop-using-loading-spinner-theres-something-better/facebook-skeleton-loading-website.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Skeleton Loading used in Facebook&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./stop-using-loading-spinner-theres-something-better/medium-skeleton-loading-website.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Loading seen on &lt;a href=&quot;https://medium.com/&quot;&gt;Medium.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You might argue that these websites use Loading Spinners. But notice how it is used. A Spinner alone is not displayed from start to finish. It is shown only for a brief period, followed by the Skeleton Screen.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;
If your load time is longer, you can briefly display a Loading Spinner, before Skeleton UI. This can buy your task some more time to complete.&lt;/p&gt;
&lt;h4&gt;Progressive Loading for Images&lt;/h4&gt;
&lt;p&gt;You can even apply gradual progression to image loading. For example, Medium and Google use progressive loading for their images.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./stop-using-loading-spinner-theres-something-better/google_progressive_loading.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Progressive Loading in Google Image Search&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./stop-using-loading-spinner-theres-something-better/medium_progressive_image_loading.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Progressive Image Loading in Medium&lt;/p&gt;
&lt;p&gt;I’m sure you’ve seen either one of these. Maybe you didn’t know it had a proper name until now.&lt;/p&gt;
&lt;p&gt;Here are the generic steps on progressive loading for images.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Display the skeleton screen&lt;/li&gt;
&lt;li&gt;Load a very low quality (pixelated) version of the image (or prominent color)&lt;/li&gt;
&lt;li&gt;Load the high-quality image in background&lt;/li&gt;
&lt;li&gt;Fade in the high-quality image, replacing the previous low-quality one&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Of course, what to display first varies. Medium chooses to use an extremely small pixelated image and applies a blur filter over it. Later it loads a higher quality image to replace it. Whereas Google displays the image’s prominent color first.&lt;/p&gt;
&lt;p&gt;Note that you’ve not given then a clear indication of WHEN the task will complete. There is still no solid time estimate. But you have told that what has completed and what remains. That itself is clear sign of progress.&lt;/p&gt;
&lt;h3&gt;Skeleton Screens on Android and iOS&lt;/h3&gt;
&lt;p&gt;You might argue saying most of the skeleton screen examples are websites. So how do I do this on mobile? You’re absolutely right. Reading all this wouldn’t be worth it if I didn’t even give you hint on how to do this.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Facebook has written a library called Shimmer for both&lt;/strong&gt; &lt;a href=&quot;https://github.com/facebook/shimmer-android&quot;&gt;&lt;strong&gt;Android&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;and&lt;/strong&gt; &lt;a href=&quot;https://github.com/facebook/Shimmer&quot;&gt;&lt;strong&gt;iOS&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It works just like how Facebook using skeleton UI to load incoming content. The shimmer animation depicts that content is currently loading.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/stop-using-loading-spinner-theres-something-better/shimmer.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Shimmer by Facebook&lt;/p&gt;
&lt;p&gt;You can use this library to display skeleton screens to denote loading in your apps.&lt;/p&gt;
&lt;h3&gt;Handling Failure with Skeleton Screens&lt;/h3&gt;
&lt;p&gt;There’s no guarantee that a request will always execute successfully. So we cannot assume that if a content loads gradually, it will eventually complete. Chances are, it might fail mid-way. The most common reasons include faulty, slow or no connectivity.&lt;/p&gt;
&lt;p&gt;Assume you’ve started a request to load content. Next, the skeleton screen is also displayed. Then suddenly, your internet goes off. How would you handle this?&lt;/p&gt;
&lt;p&gt;Typically, you must inform the user and allow them to retry.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://material.uplabs.com/posts/no-internet-connection-interface&quot;&gt;No internet connection by Dima Karpushin on material.uplabs.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Remember that giving feedback is good interaction design and positive user experience.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Empty states occur when an item’s content can’t be shown.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;
Consider using ‘ &lt;a href=&quot;https://blog.iamsuleiman.com/empty-states-advantage-user-retention/&quot;&gt;Empty States&lt;/a&gt; ’. It allows you to provide clear feedback with a ‘Call to Action’ (CTA) button.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://material.uplabs.com/posts/reminders-empty-state&quot;&gt;Reminders Empty State by Salman Hossain Saif&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Connectivity in Android and iOS&lt;/h3&gt;
&lt;p&gt;Here are a couple of resources that can help you handle connectivity.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Android&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/material-design-snackbar/&quot;&gt;Use Snackbar to provide feedback with CTA button&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gist.github.com/emil2k/5130324&quot;&gt;Connectivity&lt;/a&gt; - network handling class&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;iOS - Swift&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/vsouza/awesome-ios#alerts&quot;&gt;iOS Alerts&lt;/a&gt; - collection of alert libraries to chose from&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ashleymills/Reachability.swift&quot;&gt;Reachability&lt;/a&gt; - network handling&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Wrapping Up&lt;/h2&gt;
&lt;p&gt;Apps are getting smart. People are starting to realize that the Loading Spinner is hurting their UX. It&apos;s about time you did too.&lt;/p&gt;
&lt;p&gt;Skeleton screens provide incremental progress in loading your interface. Such incremental feedback gives better user experience, and reduces uncertainty. Moreover, people would be willing to wait a bit longer.&lt;/p&gt;
&lt;p&gt;So what do you think about Skeleton screens? Is it a viable alternative to a Loading Spinner? Let me know in the comments below.&lt;/p&gt;
</content:encoded></item><item><title>Android App shortcuts - How and When to use them</title><link>https://blog.iamsuleiman.com/android-app-shortcuts-how-and-when-to-use-them/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/android-app-shortcuts-how-and-when-to-use-them/</guid><description>App Shortcuts were introduced Android Nougat 7.1. They allow you to access primary actions of your app directly from the launcher icon. You can also p</description><pubDate>Tue, 21 Feb 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;App Shortcuts were introduced Android Nougat 7.1. They allow you to access primary actions of your app directly from the launcher icon. You can also pin certain shortcuts to the launcher for faster access. Consider you have the Uber app and you want to book a ride home. You would normally open up the app and then book a cab with your Home as the destination. Instead of doing all this, wouldn&apos;t it be great if a there was a shortcut right in your launcher that does all this in once click? That&apos;s exactly where App Shortcuts come in. In this post, we will learn how to easily implement App Shortcuts.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;App shortcuts give users quick, easy access to up to four of your app’s actions. Each action can also be added to the home screen.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;Image credits: Google&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Design Guidelines&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Google Design Guidelines&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Before we start coding, it is essential to know the design guidelines for App Shortcuts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The shortcut icons should have a total dimension of &lt;strong&gt;48dp x 48dp&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;The Live Area (where your icon will reside) should be  &lt;strong&gt;44dp x 44dp&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;The Live area should have a solid background colour fill of Material Grey 100 (or &lt;em&gt;#F5F5F5&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;The icon should have dimensions of &lt;strong&gt;24dp x 24dp&lt;/strong&gt; at the centre for the Live Area&lt;/li&gt;
&lt;li&gt;Shadows should NOT be included&lt;/li&gt;
&lt;li&gt;The icon colour has a strong contrast with &lt;em&gt;Material Grey 100&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can read more about the guidelines &lt;a href=&quot;https://commondatastorage.googleapis.com/androiddevelopers/shareables/design/app-shortcuts-design-guidelines.pdf&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;There are 2 types of App Shortcuts:&lt;/p&gt;
&lt;h3&gt;1. Static App Shortcuts&lt;/h3&gt;
&lt;p&gt;These are generated using XML and can be updated only when the app is updated. Static App Shortcuts should be only be used for actions that are constant and core to the app. For example, the Twitter app provides shortcuts to start a Search, make a new Tweet, send a new message, etc. These actions are essential to the app and are not affected by user behaviour. Hence it makes sense to implement them as Static shortcuts.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Twitter app shortcuts&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;Adding a Static Shortcut&lt;/h4&gt;
&lt;p&gt;In &lt;strong&gt;AndroidManifest.xml&lt;/strong&gt;, we have to add some &lt;code&gt;&amp;lt;meta-data&amp;gt;&lt;/code&gt; to the launcher Activity. In practice, any Activity with the intent filter set to action &lt;code&gt;android.intent.action.MAIN&lt;/code&gt; and category &lt;code&gt;android.intent.category.LAUNCHER&lt;/code&gt; can be used for app shortcuts. In my &lt;code&gt;&amp;lt;meta-data&amp;gt;&lt;/code&gt; tag, I have specified the name as &lt;code&gt;android.app.shortcuts&lt;/code&gt; and resource as &lt;em&gt;@xml/shortcuts&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;@xml/shortcuts&lt;/em&gt; is the file where we define our static shortcuts. In your res directory, create another resource directory called xml if there already isn&apos;t one. Inside that directory, create an XML file called &lt;em&gt;shortcuts.xml&lt;/em&gt; with the following contents.&lt;/p&gt;
&lt;p&gt;Each shortcut that you define should be enclosed in a &lt;code&gt;&amp;lt;shortcut&amp;gt;&lt;/code&gt; tag.&lt;/p&gt;
&lt;h5&gt;&lt;strong&gt;Attributes explained&lt;/strong&gt;&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;android:enabled&lt;/code&gt;&lt;/strong&gt;  Boolean to enable or disable the shortcut. If a shortcut is disabled, it will not show up in the list of shortcuts in the launcher.&lt;strong&gt;NOTE:&lt;/strong&gt; If the disabled shortcut was previously pinned, it will be greyed out and clicking on it will display the message specified by the string in &lt;code&gt;android:shortcutDisabledMessage&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;android:icon&lt;/code&gt;&lt;/strong&gt;  Icon resource to display corresponding to the App Shortcut&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;android:shortcutId&lt;/code&gt;&lt;/strong&gt;  Unique identifier that allows Android to recognise your shortcut&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;android:shortcutShortLabel&lt;/code&gt;&lt;/strong&gt;  Your App Shortcut&apos;s text. It should be within 10 characters. Otherwise, it will be ellipsised.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;android:shortcutLongLabel&lt;/code&gt;&lt;/strong&gt; Label that is displayed when the shortcut is pinned to the launcher. It should have a max length of 25 characters.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Every &lt;code&gt;&amp;lt;shortcut&amp;gt;&lt;/code&gt; needs to have at least one &lt;code&gt;&amp;lt;intent&amp;gt;&lt;/code&gt; tag that specifies what action is to be taken when a shortcut is clicked. You can have multiple &lt;code&gt;&amp;lt;intent&amp;gt;&lt;/code&gt; tags in the same shortcut but Android will handle this by using the last &lt;code&gt;&amp;lt;intent&amp;gt;&lt;/code&gt;. It places all the previous intents in the backstack. That&apos;s all you need to get static shortcuts running.&lt;/p&gt;
&lt;h3&gt;2. Dynamic App Shortcuts&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Telegram app shortcuts&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Dynamic shortcuts can be generated and destroyed at runtime. They are used for actions customised to the user&apos;s behaviour. For example, the Telegram app provides shortcuts to your most frequented chats.&lt;/p&gt;
&lt;h4&gt;Adding a Dynamic Shortcut&lt;/h4&gt;
&lt;p&gt;In order to add, remove or update dynamic shortcuts, we need to use the &lt;code&gt;ShortcutManager&lt;/code&gt; class.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s create our Intent that will be used by our shortcut.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Intent intent = new Intent(this, DynamicShortcutActivity.class);
intent.setAction(Intent.ACTION_VIEW);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To create a new shortcut, we have to use &lt;code&gt;ShortcutInfo&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ShortcutInfo dynamicShortcut = new ShortcutInfo.Builder(this, &quot;dyanmicShortcut&quot;)
                .setShortLabel(&quot;Dynamic&quot;)
                .setLongLabel(&quot;Open dynamic shortcut&quot;)
                .setIcon(Icon.createWithResource(this, R.drawable.ic_dynamic))
                .setIntent(intent)
                .setRank(0)
                .build();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here &lt;code&gt;dyanmicShortcut&lt;/code&gt; is the id given to the shortcut. The &lt;code&gt;setRank()&lt;/code&gt; method is used to position the shortcut in the list, 0(zero) being the lowest positioned one. Now that we have our shortcut ready, we need to set it as a Dynamic Shortcut.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;shortcutManager.setDynamicShortcuts(Collections.singletonList(dynamicShortcut));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;setDynamicShortcuts()&lt;/code&gt; method takes an Array. Since we have only shortcut, I have a created a Singleton List. Finally, add an &lt;code&gt;&amp;lt;intent-filter&amp;gt;&lt;/code&gt; to the DynamicShortcutActivity in &lt;strong&gt;AndroidManifest.xml&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;That&apos;s it, we&apos;re done! Now our Dynamic Shortcut is ready to roll. Run your app and long press the app icon in the launcher. You should see something like this:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;App shortcuts demo&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;Disabling a Shortcut&lt;/h4&gt;
&lt;p&gt;To disable a certain dynamic shortcut, we can use the &lt;code&gt;disableShortcuts()&lt;/code&gt; method. It takes an array of shortcut ids as parameter&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;shortcutManager.disableShortcuts(Collections.singletonList(dynamicShortcut));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: You can have a maximum of 5 App Shortcut. The number of shortcuts should be chosen carefully. Attempting to use more than 5 will result in a crash. Not all launchers support app shortcuts. Make sure to test in on launchers that have App Shortcuts support (like &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.teslacoilsw.launcher&amp;amp;hl=en&quot;&gt;Nova launcher&lt;/a&gt;).&lt;/p&gt;
&lt;h3&gt;When not to use App Shortcuts&lt;/h3&gt;
&lt;p&gt;App shortcuts should be used only for the most commonly used features of the app. Let us consider WhatsApp as an example. The ideal shortcuts for it would be the &apos;&lt;em&gt;most frequent chats&lt;/em&gt;&apos;. This is where the user spends the most time on the app. Hence it makes sense to include them in the shortcuts. But it should not be used for actions like creating a new group as it is not a core or frequently used feature. Using shortcuts for actions the user does not use that often beats the point of having shortcuts altogether.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Final Result&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/android-app-shortcuts-how-and-when-to-use-them/l3q2xDQaeq94UizIs.gif&quot; alt=&quot;App shortcut demo gif&quot; title=&quot;App shortcut demo&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Source Code:&lt;/strong&gt; &lt;a href=&quot;https://github.com/SubhrajyotiSen/AppShortcuts&quot;&gt;View Project on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Quick Recap&lt;/h3&gt;
&lt;p&gt;In this post, we learnt&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What App Shortcuts are&lt;/li&gt;
&lt;li&gt;How are Static and Dynamic Shortcuts different&lt;/li&gt;
&lt;li&gt;Implementation of both types of shortcuts&lt;/li&gt;
&lt;li&gt;When to avoid using App Shortcuts and why&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What do you think about App Shortcuts? Have you implemented them in your apps? I&apos;d love to hear from you in the comments. Don&apos;t forget to subscribe for some awesome posts coming soon.&lt;/p&gt;
</content:encoded></item><item><title>Using Bottom Navigation View - Android Design Support Library</title><link>https://blog.iamsuleiman.com/using-bottom-navigation-view-android-design-support-library/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/using-bottom-navigation-view-android-design-support-library/</guid><description>_This tutorial is now updated for AndroidX!_ Android Bottom Bar (Bottom Navigation View) was officially added in Design Support Library v25. Bottom Ba</description><pubDate>Tue, 31 Jan 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;This tutorial is now updated for AndroidX!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Android Bottom Bar (Bottom Navigation View) was officially added in Design Support Library v25. Bottom Bar was first introduced in the Material Design guidelines.&lt;/p&gt;
&lt;p&gt;Initially, it was met with some reception. People had polarizing opinions on it. Even I, was on the negative spectrum of thought.The fact that it had existed on iOS for so long, now felt like a poor rip-off for Android.&lt;/p&gt;
&lt;p&gt;However, usability studies say that &lt;a href=&quot;https://techcrunch.com/2014/05/24/before-the-hamburger-button-kills-you/&quot;&gt;Bottom Navigation trumps the Navigation Drawer&lt;/a&gt;. That’s when I felt its introduction was actually, well thought of.&lt;/p&gt;
&lt;p&gt;But irrespective of our opinions, Bottom Navigation is here to stay. It is now officially supported in Android’s Design Support Library, as of version 25.0.0.&lt;/p&gt;
&lt;h2&gt;Bottom Navigation Bar - Getting Started&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Bottom navigation bars make it easy to explore and switch between top-level views in a single tap. – &lt;a href=&quot;https://material.io/guidelines/components/bottom-navigation.html#bottom-navigation-usage&quot;&gt;material.io&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./using-bottom-navigation-view-android-design-support-library/bottom_navigation_bar_google_plus.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Bottom Navigation in Google+ app&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./using-bottom-navigation-view-android-design-support-library/bottom_navigation_bar_instagram.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Bottom Navigation in Instagram Android app&lt;/p&gt;
&lt;p&gt;Some of you might wonder why I’m writing another post on Bottom Navigation.&lt;/p&gt;
&lt;p&gt;When Bottom Navigation was added to the &lt;a href=&quot;https://material.io/components/bottom-navigation/&quot;&gt;Material Design spec&lt;/a&gt;, there was no official support for it. This paved way for (unofficial) third-party libraries.&lt;/p&gt;
&lt;p&gt;Now I’m not saying those libraries are bad in any way. Those who know me, will know that I encourage using third-party libraries when possible.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;READ&lt;/strong&gt;&lt;br /&gt;
&lt;a href=&quot;https://blog.iamsuleiman.com/bottom-navigation-bar-android-tutorial/&quot;&gt;Easy Bottom Navigation Tutorial with a custom library&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The above article includes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Easy third-party implementation&lt;/li&gt;
&lt;li&gt;when to use Bottom Navigation and the difference with Navigation Drawer&lt;/li&gt;
&lt;li&gt;transition animations&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;However, if you want to use the official libraries (which are equally good, if not, better), read on below!&lt;/p&gt;
&lt;p&gt;The Design Support Library is so popular, chances are that you’re already using it. Since it now includes &lt;code&gt;BottomNavigationView&lt;/code&gt;, it might make little sense to rely on third-party.&lt;/p&gt;
&lt;h3&gt;Adding Dependencies&lt;/h3&gt;
&lt;p&gt;Start by adding the relevant support library dependencies.&lt;/p&gt;
&lt;p&gt;dependencies {
...
implementation &apos;androidx.appcompat:appcompat:1.1.0&apos;
&lt;strong&gt;implementation &apos;com.google.android.material:material:1.0.0&apos;&lt;/strong&gt;
// Other Dependencies
}&lt;/p&gt;
&lt;h3&gt;Adding BottomNavigationView to Layout&lt;/h3&gt;
&lt;p&gt;Now, add the Bottom Bar to your &lt;em&gt;layout.xml&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&amp;lt;com.google.android.material.bottomnavigation.BottomNavigationView
android:layout_width=&quot;match_parent&quot;
android:layout_height=&quot;wrap_content&quot;
android:layout_gravity=&quot;bottom&quot;
**  app:itemBackground=&quot;?attr/colorPrimary&quot;
**       &lt;strong&gt;app:itemIconTint=&quot;@drawable/selector_bottombar&quot;&lt;/strong&gt;
&lt;strong&gt;app:itemTextColor=&quot;@drawable/selector_bottombar&quot;&lt;/strong&gt;
app:menu=&quot;@menu/bottombar_menu&quot;/&amp;gt;&lt;/p&gt;
&lt;p&gt;I’ve taken the liberty to add some basic styling here. As you can see, we’re allowed to set a few basic color properties.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UX DESIGN TIP&lt;/strong&gt;&lt;br /&gt;
Remember to keep your non-active tab items (icon+text) visible at all times so people know what they are, even when its not active.&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;Adding Bottom&lt;/strong&gt; Navigation &lt;strong&gt;Items&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Create a new &lt;em&gt;&lt;strong&gt;bottombar_menu.xml&lt;/strong&gt;&lt;/em&gt; under &lt;em&gt;…res/menu/&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;bottombar_menu.xml&lt;/em&gt;&lt;/p&gt;

&lt;menu&gt;
&lt;pre&gt;&lt;code&gt; &amp;lt;item
    android:id=&quot;@+id/bottombaritem_calls&quot;
    android:icon=&quot;@drawable/ic_call_24dp&quot;
    android:title=&quot;Calls&quot;
    app:showAsAction=&quot;ifRoom&quot;/&amp;gt;

&amp;lt;item
    android:id=&quot;@+id/bottombaritem_recents&quot;
    android:icon=&quot;@drawable/ic_query_builder_24dp&quot;
    android:title=&quot;Recents&quot;
    app:showAsAction=&quot;ifRoom&quot;/&amp;gt;

&amp;lt;item
    android:id=&quot;@+id/bottombaritem_trips&quot;
    android:icon=&quot;@drawable/ic_flight_24dp&quot;
    android:title=&quot;Trips&quot;
    app:showAsAction=&quot;ifRoom&quot;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/menu&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
It is recommended to have at least 3, and at most 5 items in Bottom Navigation.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Connecting Bottom Navigation in Activity.java&lt;/h3&gt;
&lt;p&gt;Head over to your &lt;em&gt;Activity.java&lt;/em&gt;. Initialize your UI.&lt;/p&gt;
&lt;p&gt;public class BottomBarActivity extends AppCompatActivity {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private BottomNavigationView bottomNavigationView;
...

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_bottom_bar);

    bottomNavigationView = findViewById(R.id.bottom_nav);

  ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;...
}&lt;/p&gt;
&lt;h4&gt;Listen for Item clicks&lt;/h4&gt;
&lt;p&gt;We can listen and react to individual item clicks of Bottom Navigation. We do this using &lt;code&gt;BottomNavigationView. setOnNavigationItemSelectedListener()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;bottomNavigationView.setOnNavigationItemSelectedListener(
new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.action_bottombar_calls:
// TODO
return true;
case R.id.action_bottombar_recents:
// TODO
return true;
case R.id.action_bottombar_trips:
// TODO
return true;
}
return false;
}
});&lt;/p&gt;
&lt;p&gt;Now we have a basic Bottom Navigation set up for our app. Why not run it and see how it looks?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./using-bottom-navigation-view-android-design-support-library/bottomnav_samestates.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Our Bottom Navigation seems to register clicks. But something seems off. Did you notice?&lt;/p&gt;
&lt;p&gt;Our very first navigation item ‘Calls’ is selected by default alright.&lt;/p&gt;
&lt;h5&gt;But something doesn’t seem right&lt;/h5&gt;
&lt;p&gt;I don’t know about you, but I don’t see any state difference.&lt;/p&gt;
&lt;p&gt;Meaning, visually, there’s hardly any difference between items that are resting, and the active item. In short, there is not enough visual contrast to differentiate the two.&lt;/p&gt;
&lt;p&gt;Take a good look at our Bottom Navigation. Now see how it looks like on the Material Docs.&lt;/p&gt;
&lt;p&gt;Image credit - &lt;a href=&quot;http://material.io&quot;&gt;material.io&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Surely both don’t look the same!&lt;/p&gt;
&lt;p&gt;Something has to be done about that. We can quickly take care of this by using &lt;strong&gt;XML selectors&lt;/strong&gt;.&lt;/p&gt;
&lt;h4&gt;Bottom Navigation Styling - Selector States&lt;/h4&gt;
&lt;p&gt;Going by our XML, our Bottom Nav&apos;s background is colored. We want to light up our active item with 100% white and want the inactive ones dim. So let&apos;s say the inactive tab items are at 40% white. Here is the XML selectors for the same.&lt;/p&gt;
&lt;p&gt;Create &lt;em&gt;&lt;strong&gt;selector_bottombar_item.xml&lt;/strong&gt;&lt;/em&gt; under &lt;em&gt;…res/drawable/&lt;/em&gt;.&lt;/p&gt;

    
    
    

&lt;p&gt;Modify your &lt;code&gt;Activity&lt;/code&gt;’s &lt;code&gt;BottomNavigationView&lt;/code&gt; widget to use this selector.&lt;/p&gt;
&lt;p&gt;...&lt;br /&gt;
&amp;lt;&lt;strong&gt;com.google.android.material.bottomnavigation.BottomNavigationView&lt;/strong&gt;
android:id=&quot;@+id/bottom_nav&quot;
...
app:itemIconTint=&quot;@drawable/selector_bottombar&quot;
app:itemTextColor=&quot;@drawable/selector_bottombar&quot;
app:menu=&quot;@menu/bottombar_menu&quot;/&amp;gt;
...&lt;/p&gt;
&lt;p&gt;Run your app again.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./using-bottom-navigation-view-android-design-support-library/bottomnavigationview-styling.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Much better right?&lt;/p&gt;
&lt;p&gt;Before moving onto the next section, why don’t you take a breather?&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Creating Screens for Bottom Navigation Items&lt;/h2&gt;
&lt;p&gt;If you recall the guidelines, &lt;code&gt;BottomNavigationView&lt;/code&gt; navigates between top-level views.&lt;/p&gt;
&lt;p&gt;Think carefully, the top-level view(s) here would be the visible space above the Bottom Navigation.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./using-bottom-navigation-view-android-design-support-library/bottomnav_top_level_view_fragment.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This visible space must reflect the currently active Bottom Navigation Item.&lt;/p&gt;
&lt;p&gt;So if the ‘Calls’ item is currently active (highlighted or selected) in our Bottom Navigation, then the visible space must show the Calls screen.&lt;/p&gt;
&lt;p&gt;We can do this using &lt;a href=&quot;https://developer.android.com/guide/components/fragments.html&quot;&gt;&lt;code&gt;Fragment&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let’s hook up our &lt;code&gt;BottomNavigationView&lt;/code&gt; with some &lt;code&gt;Fragments&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Creating Fragments&lt;/h3&gt;
&lt;p&gt;For simplicity, I will use a single &lt;code&gt;Fragment&lt;/code&gt;, with slight UI changes that denote each navigation item.&lt;/p&gt;
&lt;p&gt;Create class &lt;strong&gt;BottomBarFragment.java&lt;/strong&gt;. The only thing that I’ll be doing here is include a &lt;code&gt;TextView&lt;/code&gt;. It will reflect the name of the current Bottom Navigation item.&lt;/p&gt;
&lt;p&gt;public class BottomBarFragment extends Fragment {
public static final String ARG_TITLE = &quot;arg_title&quot;;
private TextView textView;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_bottom_bar, container, false);

    textView =  rootView.findViewById(R.id.fragment_bottom_bar_text_activetab);

    String title = getArguments().getString(ARG_TITLE, &quot;&quot;);
    textView.setText(title);
  ...
    return rootView;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Layout Design&lt;/strong&gt;&lt;br /&gt;
Here’s what I’ve created. Something simple enough where the &lt;code&gt;TextView&lt;/code&gt; denotes the current active navigation item.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./using-bottom-navigation-view-android-design-support-library/bottombar_fragmentlayout.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;fragment_bottom_bar.xml&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Modifying Activity layout to support Fragments&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Go back to your &lt;code&gt;Activity&lt;/code&gt;’s XML layout. We need a &lt;code&gt;FrameLayout&lt;/code&gt; that will host our &lt;code&gt;Fragment&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;FrameLayout
    android:id=&quot;@+id/frame_fragmentholder&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    android:layout_marginBottom=&quot;?attr/actionBarSize&quot;/&amp;gt;     
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;com.google.android.material.bottomnavigation.BottomNavigationView /&amp;gt;&lt;/p&gt;

&lt;h4&gt;Inflating Fragments&lt;/h4&gt;
&lt;p&gt;Go back to &lt;em&gt;BottomBarActivity.java&lt;/em&gt;. We need to do 2 things.&lt;/p&gt;
&lt;h5&gt;1. Build a list of our Fragments. One for each Navigation item&lt;/h5&gt;
&lt;p&gt;Declare a &lt;code&gt;List&amp;lt;BottomBarFragment&amp;gt;&lt;/code&gt; of &lt;code&gt;Fragments&lt;/code&gt; that will hold all the &lt;code&gt;Fragments&lt;/code&gt; for our Bottom Navigation.&lt;/p&gt;
&lt;p&gt;private List fragments = new ArrayList&amp;lt;&amp;gt;(3);&lt;/p&gt;
&lt;p&gt;We need a &lt;code&gt;List&lt;/code&gt; of size 3 since our Bottom Navigation contains 3 items.&lt;/p&gt;
&lt;p&gt;private void buildFragmentsList() {
BottomBarFragment callsFragment = buildFragment(&quot;Calls&quot;);
BottomBarFragment recentsFragment = buildFragment(&quot;Recents&quot;);
BottomBarFragment tripsFragment = buildFragment(&quot;Trips&quot;);&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    fragments.add(callsFragment);
    fragments.add(recentsFragment);
    fragments.add(tripsFragment);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we’ll define the &lt;code&gt;buildFragment()&lt;/code&gt; method. It’s job is to initialize each &lt;code&gt;BottomBarFragment&lt;/code&gt; to hold the correct Bottom Navigation item title.&lt;/p&gt;
&lt;p&gt;private BottomBarFragment buildFragment(String title) {
BottomBarFragment fragment = new BottomBarFragment();
Bundle bundle = new Bundle();
bundle.putString(BottomBarFragment.ARG_TITLE, title);
fragment.setArguments(bundle);
return fragment;
}&lt;/p&gt;
&lt;p&gt;We now have a list of fragments that hold 3 &lt;em&gt;BottomBarFragment&lt;/em&gt;. Each &lt;code&gt;Fragment&lt;/code&gt; here holds its respective Bottom Navigation item title. The fragments in the &lt;code&gt;List&lt;/code&gt; are in the same order as the Bottom Navigation items.&lt;/p&gt;
&lt;h5&gt;2. Inflate Fragment based on position&lt;/h5&gt;
&lt;p&gt;Lastly, we inflate the correct &lt;code&gt;Fragment&lt;/code&gt; of the 3, into our &lt;code&gt;FrameLayout&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let’s write a generic method that handles the &lt;code&gt;Fragment&lt;/code&gt; switching for us.&lt;/p&gt;
&lt;p&gt;private void switchFragment(int pos, String tag) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.frame_fragmentholder, fragments.get(pos), tag)
.commit();
}&lt;/p&gt;
&lt;p&gt;There are 2 scenarios to handle:&lt;/p&gt;
&lt;h5&gt;a. App launch&lt;/h5&gt;
&lt;p&gt;We need to show a &lt;code&gt;Fragment&lt;/code&gt; by default, when the app launches. This would obviously be the very first item in the Bottom Navigation, ‘Calls’ item.&lt;/p&gt;
&lt;p&gt;Add this line in &lt;code&gt;BottomBarActivity.onCreate()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;// Set the 0th Fragment to be displayed by default.
switchFragment(0, TAG_FRAGMENT_CALLS);&lt;/p&gt;
&lt;p&gt;It would be wise to maintain constant tags to uniquely identify each &lt;code&gt;Fragment&lt;/code&gt; (Bottom Navigation Item).&lt;/p&gt;
&lt;p&gt;private static final String TAG_FRAGMENT_CALLS = &quot;tag_frag_calls&quot;;
private static final String TAG_FRAGMENT_RECENTS = &quot;tag_frag_recents&quot;;
private static final String TAG_FRAGMENT_TRIPS = &quot;tag_frag_trips&quot;;&lt;/p&gt;
&lt;h5&gt;b. Bottom Navigation item clicks&lt;/h5&gt;
&lt;p&gt;When a Bottom Navigation item is clicked, the view is changed. In relative terms, we show the relevant &lt;em&gt;BottomBarFragment.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Modify your &lt;code&gt;BottomNavigationView&lt;/code&gt; item click listener as follows.&lt;/p&gt;
&lt;p&gt;bottomNavigationView.setOnNavigationItemSelectedListener(
new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.action_bottombar_calls:
switchFragment(0, TAG_FRAGMENT_CALLS);
return true;
case R.id.action_bottombar_recents:
switchFragment(1, TAG_FRAGMENT_RECENTS);
return true;
case R.id.action_bottombar_trips:
switchFragment(2, TAG_FRAGMENT_TRIPS);
return true;
}
return false;
}
});&lt;/p&gt;
&lt;p&gt;Here’s the complete &lt;em&gt;BottomBarActivity.java&lt;/em&gt; for your reference.&lt;/p&gt;
&lt;p&gt;public class BottomBarActivity extends AppCompatActivity {
private static final String TAG_FRAGMENT_CALLS = &quot;tag_frag_calls&quot;;
private static final String TAG_FRAGMENT_RECENTS = &quot;tag_frag_recents&quot;;
private static final String TAG_FRAGMENT_TRIPS = &quot;tag_frag_trips&quot;;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private BottomNavigationView bottomNavigationView;
/\*\*
 \* Maintains a list of Fragments for {@link BottomNavigationView}
 \*/
private List&amp;lt;BottomBarFragment&amp;gt; fragments = new ArrayList&amp;lt;&amp;gt;(3);

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_bottom_bar);

    bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_nav);

    bottomNavigationView.setOnNavigationItemSelectedListener(
            new BottomNavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                    switch (item.getItemId()) {
                        case R.id.action_bottombar_calls:
                            switchFragment(0, TAG_FRAGMENT_CALLS);
                            return true;
                        case R.id.action_bottombar_recents:
                            switchFragment(1, TAG_FRAGMENT_RECENTS);
                            return true;
                        case R.id.action_bottombar_trips:
                            switchFragment(2, TAG_FRAGMENT_TRIPS);
                            return true;
                    }
                    return false;
                }
            });

    buildFragmentsList();

    // Set the 0th Fragment to be displayed by default.
    switchFragment(0, TAG_FRAGMENT_CALLS);

}

private void switchFragment(int pos, String tag) {
    getSupportFragmentManager()
            .beginTransaction()
            .replace(R.id.frame_fragmentholder, fragments.get(pos), tag)
            .commit();
}

private void buildFragmentsList() {
    BottomBarFragment callsFragment = buildFragment(&quot;Calls&quot;);
    BottomBarFragment recentsFragment = buildFragment(&quot;Recents&quot;);
    BottomBarFragment tripsFragment = buildFragment(&quot;Trips&quot;);

    fragments.add(callsFragment);
    fragments.add(recentsFragment);
    fragments.add(tripsFragment);
}

private BottomBarFragment buildFragment(String title) {
    BottomBarFragment fragment = new BottomBarFragment();
    Bundle bundle = new Bundle();
    bundle.putString(BottomBarFragment.ARG_TITLE, title);
    fragment.setArguments(bundle);
    return fragment;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Wow, that took longer than expected! Now with everything done, go ahead and run the app.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/using-bottom-navigation-view-android-design-support-library/bottom_navigation_bar_transition.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;If your app looks similar to that, give yourselves a pat on the back.&lt;/p&gt;
&lt;p&gt;Congratulations! We’ve successfully added Bottom Navigation to our apps.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Source Code:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Suleiman19/Android-Material-Design-for-pre-Lollipop/blob/master/MaterialSample/app/src/main/java/com/suleiman/material/activities/BottomBarActivity.java&quot;&gt;View Project on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Quick Recap&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In this article, we set up a &lt;code&gt;BottomNavigationView&lt;/code&gt; and reacted to item clicks. Then we looked into styling options with XML selectors. Finally, we saw how to set up navigation between &lt;code&gt;Fragments&lt;/code&gt; using the Bottom Navigation Items.&lt;/p&gt;
&lt;p&gt;Now all that’s left is for you to decide what content goes into each &lt;code&gt;Fragment&lt;/code&gt;. I am sure you will create something great. Good luck with that!&lt;/p&gt;
&lt;p&gt;Is there anything you’d like to add to this article? Let me know in the comments.&lt;/p&gt;
&lt;p&gt;If you liked reading this article, share it to your social network.&lt;/p&gt;
</content:encoded></item><item><title>Material Design Snackbar in Android - How and When to Use</title><link>https://blog.iamsuleiman.com/material-design-snackbar/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/material-design-snackbar/</guid><description>Snackbar was introduced in Material Design. It is available via the Design Support Library. Code-wise, it is similar to a Toast. In this article, we’l</description><pubDate>Tue, 24 Jan 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code&gt;Snackbar&lt;/code&gt; was introduced in Material Design. It is available via the Design Support Library. Code-wise, it is similar to a &lt;code&gt;Toast.&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In this article, we’ll first clear the confusion around using &lt;code&gt;Snackbar&lt;/code&gt; and &lt;code&gt;Toast&lt;/code&gt;. Next, we’ll look at implementation and customizing.&lt;/p&gt;
&lt;p&gt;But before that, let’s clarify what exactly a &lt;code&gt;Snackbar&lt;/code&gt; is.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;#using-material-design-snackbar&quot;&gt;Already know what it is? Jump straight to the code.&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;What is Snackbar?&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;A lightweight component that gives feedback to users. It optionally provides an action to users.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./material-design-snackbar/snackbar.png&quot; alt=&quot;Simple Material Design Snackbar in Android&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Behavior&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Snackbars are displayed at the bottom of the screen. It stays there for the specified interval. Or, you can dismiss it by swiping.&lt;/p&gt;
&lt;p&gt;However, there arises a confusion with our ‘ol pal, the &lt;a href=&quot;https://developer.android.com/guide/topics/ui/notifiers/toasts.html&quot;&gt;&lt;code&gt;Toast&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Snackbar VS Toast Confusion&lt;/h3&gt;
&lt;p&gt;The addition of a &lt;code&gt;Snackbar&lt;/code&gt; created ambiguity. When do we use it and when to use &lt;code&gt;Toast&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;Its important that we know what to use when. So before moving on to actual code implementation, let’s clear the confusion.&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;The Difference&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Snackbar&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Contain a single line of text directly related to the operation performed. They may contain a text action, but no icons.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;Lightweight feedback about an operation&lt;/li&gt;
&lt;li&gt;Optionally includes a single action&lt;/li&gt;
&lt;li&gt;Can optionally stay on-screen permanently, until swiped off screen&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Toast&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./material-design-snackbar/toast.png&quot; alt=&quot;Simple Android Toast message&quot; /&gt;&lt;/p&gt;
&lt;p&gt;A simple Toast&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Primarily used for system messaging. They also display at the bottom of the screen, but may not be swiped off-screen.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;System-level messaging&lt;/li&gt;
&lt;li&gt;No user action can be performed&lt;/li&gt;
&lt;li&gt;Can only stay on screen temporarily. Cannot be swiped&lt;/li&gt;
&lt;/ol&gt;
&lt;h5&gt;Moving forward&lt;/h5&gt;
&lt;p&gt;Now that we’re clear about difference between the two, we can start implementing.&lt;/p&gt;
&lt;p&gt;First, we’ll look at using a simple usage, right off the bat. Next I’ll tell you how to include a primary action. Then we’ll learn how to style it. Finally, we’ll go over its do’s and don&apos;ts.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Usage&lt;/h3&gt;
&lt;p&gt;Displaying is relatively simple. In fact, it is similar to how you would write a &lt;code&gt;Toast&lt;/code&gt;. We use the class  &lt;code&gt;android.support.design.widget.Snackbar&lt;/code&gt; .&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Snackbar  
    .make(view, &quot;Your message here&quot;,               
                Snackbar.LENGTH_SHORT)
    .show();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;view&lt;/code&gt; (1st parameter) doesn’t have to be your parent layout. It can be any &lt;code&gt;View&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;
Ideally, &lt;code&gt;Snackbar&lt;/code&gt; works best if your parent layout is a &lt;code&gt;CoordinatorLayout&lt;/code&gt;. This ensures that it plays nice with other UI elements (such as FAB). More on that later.&lt;/p&gt;
&lt;p&gt;Next, the duration for displaying (3rd parameter), can be any of the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;LENGTH_INDEFINITE&lt;/li&gt;
&lt;li&gt;LENGTH_LONG&lt;/li&gt;
&lt;li&gt;LENGTH_SHORT&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I hope the duration types above are self-explanatory.&lt;/p&gt;
&lt;p&gt;LENGTH_INDEFINITE will show the &lt;code&gt;Snackbar&lt;/code&gt; for and indefinite period of time. But you can dismiss it by swiping.&lt;/p&gt;
&lt;p&gt;Finally, don’t forget to call &lt;code&gt;Snackbar.show()&lt;/code&gt; .&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
For &lt;code&gt;Snackbar&lt;/code&gt; to work, your &lt;code&gt;Activity&lt;/code&gt; must inherit from (extend) &lt;code&gt;AppCompatActivity&lt;/code&gt;. Otherwise, consider a third-party alternative.&lt;/p&gt;
&lt;h4&gt;Adding a Primary Action&lt;/h4&gt;
&lt;p&gt;As stated in the Material Design spec, we can optionally include an action.&lt;/p&gt;
&lt;p&gt;Adding a user action is relatively simple. Simply modify your existing call as follows.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Snackbar  
    .make(view, &quot;Your message here&quot;,               
                Snackbar.LENGTH_SHORT)
    .setAction(&quot;YourAction&quot;, new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        // TODO: Your Action
                    }
                });
    .show()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ideal use-cases for a primary action include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;UNDO - for deleted message, archive, etc&lt;/li&gt;
&lt;li&gt;CONNECT - to enable internet if disconnected&lt;/li&gt;
&lt;li&gt;RETRY - an action that failed (e.g. API call)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
Do not include an action for DISMISS. This is of no use. Just auto-dismiss your &lt;code&gt;Snackbar&lt;/code&gt; by setting a short duration. Or it can simply be swiped away.&lt;/p&gt;
&lt;h4&gt;Styling&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;./material-design-snackbar/snackbar-color-breakdown.png&quot; alt=&quot;default Material Design style specs Snackbar&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Default properties&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Snackbar&lt;/code&gt; class follows the &lt;a href=&quot;http://www.journaldev.com/1425/builder-design-pattern-in-java&quot;&gt;Builder pattern&lt;/a&gt; which allows for easy styling.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Action Text color&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;snackbar.setActionTextColor(
      ContextCompat.getColor(
          context, R.color.yourColor)
      );
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To style properties such as text colors, you’ll have to fetch the &lt;code&gt;View&lt;/code&gt; first.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;View snackbarView = snackbar.getView();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then get the &lt;code&gt;TextView&lt;/code&gt; from it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TextView textView = (TextView) snackbarView.findViewById(
       android.support.design.R.id.snackbar_text);

// For multi-line text, limit max line count.
textView.setMaxLines(3);

 // Snackbar text color (not action button)
 textView.setTextColor(yourColor);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./material-design-snackbar/multiline-snackbar.png&quot; alt=&quot;multi-line textview Snackbar&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Background color&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;First, you’ll need a reference. Then apply all your style properties and finally call &lt;code&gt;snackbar.show()&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;snackbarView.setBackgroundColor(yourColor);
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Playing nice with Floating Action Button&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/material-design-snackbar/components_snackbar_usage_fabdo_005.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Have you seen this behavior before?&lt;/p&gt;
&lt;p&gt;The FAB translates up, giving space for the &lt;code&gt;Snackbar&lt;/code&gt; to rise from the bottom.&lt;/p&gt;
&lt;p&gt;This is the ideal, recommended behavior. Because the last thing we want is the FAB overlap!&lt;/p&gt;
&lt;p&gt;So to avoid that, just keep one thing in mind.&lt;/p&gt;
&lt;p&gt;Your parent layout (root layout) must be a &lt;code&gt;CoordinatorLayout&lt;/code&gt;. It ensures that the correct &lt;code&gt;Behavior&lt;/code&gt; is applied to its child Views. In other words, it ensures that UI elements ‘behave’ or ‘coordinate’ correctly.&lt;/p&gt;
&lt;p&gt;Here’s an example of how such an XML layout would look like.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;androidx.coordinatorlayout.widget.CoordinatorLayout  
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;match_parent&quot;&amp;gt;

    &amp;lt;com.google.android.material.floatingactionbutton.FloatingActionButton
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            android:layout_gravity=&quot;end|bottom&quot;
            android:src=&quot;@drawable/ic_your_icon&quot;/&amp;gt;

&amp;lt;/androidx.coordinatorlayout.widget.CoordinatorLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h4&gt;Creating a Custom Layout&lt;/h4&gt;
&lt;p&gt;With &lt;a href=&quot;https://developer.android.com/topic/libraries/support-library/revisions.html#25-1-0&quot;&gt;v25.1.0 of Android Design Support Library&lt;/a&gt;, creating a custom layout is now possible.&lt;/p&gt;
&lt;p&gt;That’s right, I’m talking about creating an XML layout of your own.&lt;/p&gt;
&lt;p&gt;We can do this in 4 simple steps.&lt;/p&gt;
&lt;h5&gt;1. Create XML layout&lt;/h5&gt;
&lt;p&gt;Now I’m going to leave this to you. Let loose your imagination!&lt;/p&gt;
&lt;p&gt;As for me, I’ll just roll in a simple layout this time.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
              xmlns:tools=&quot;http://schemas.android.com/tools&quot;
              android:layout_width=&quot;match_parent&quot;
              android:layout_height=&quot;wrap_content&quot;
              android:background=&quot;#efefef&quot;
              android:gravity=&quot;center_vertical&quot;
              android:orientation=&quot;horizontal&quot;
              android:paddingBottom=&quot;16dp&quot;
              android:paddingTop=&quot;16dp&quot;&amp;gt;

    &amp;lt;TextView
        android:id=&quot;@+id/snackbar_text&quot;
        android:layout_width=&quot;0dp&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_weight=&quot;75&quot;
        android:ellipsize=&quot;end&quot;
        android:maxLines=&quot;3&quot;
        android:paddingLeft=&quot;16dp&quot;
        android:paddingRight=&quot;16dp&quot;
        android:textAppearance=&quot;@style/TextAppearance.Design.Snackbar.Message&quot;
        tools:text=&quot;This is a custom Snackbar text&quot;/&amp;gt;

    &amp;lt;Button
        android:id=&quot;@+id/snackbar_btn&quot;
        style=&quot;@style/Widget.AppCompat.Button.Borderless&quot;
        android:layout_width=&quot;0dp&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_marginEnd=&quot;24dp&quot;
        android:layout_marginLeft=&quot;24dp&quot;
        android:layout_marginRight=&quot;24dp&quot;
        android:layout_marginStart=&quot;24dp&quot;
        android:layout_weight=&quot;25&quot;
        android:text=&quot;Action&quot;
        android:textColor=&quot;@color/colorAccent&quot;/&amp;gt;

&amp;lt;/LinearLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./material-design-snackbar/snackbar-custom-layout.png&quot; alt=&quot;Custom Snackbar layout_design support library v25.1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Custom layout&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./material-design-snackbar/snackbar-custom-layout-blueprint.png&quot; alt=&quot;Custom Snackbar layout blueprint_design support library v25.1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Custom layout- Blueprint&lt;/p&gt;
&lt;h5&gt;2. Create a Custom class&lt;/h5&gt;
&lt;p&gt;Create a &lt;em&gt;CustomSnackbar&lt;/em&gt; final class that extends &lt;code&gt;BaseTransientBottomBar&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Next, create an inner, static class &lt;em&gt;ContentViewCallback&lt;/em&gt;. Implement the &lt;code&gt;BaseTransientBottomBar.ContentViewCallback&lt;/code&gt; interface.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class CustomSnackbar 
        extends BaseTransientBottomBar&amp;lt;CustomSnackbar&amp;gt; {
    
    ...
    
     private static class ContentViewCallback
            implements BaseTransientBottomBar.ContentViewCallback {

     // view inflated from custom layout
        private View view;

        public ContentViewCallback(View view) {
            this.view = view;
        }

        @Override
        public void animateContentIn(int delay, int duration) {
            // TODO: handle enter animation
        }

        @Override
        public void animateContentOut(int delay, int duration) {
            // TODO: handle exit animation
        }
    }
   ... 
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, our main layout is inflated and taken care of. Next is handling the &lt;code&gt;TextView&lt;/code&gt; and action &lt;code&gt;Button&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But keep in mind that a typical &lt;code&gt;Snackbar&lt;/code&gt; has this. Moreover, since my custom layout has a Text and Button too, I’m adding functionality to it.&lt;/p&gt;
&lt;p&gt;So if you don’t have either of those Views, then skip ahead to point 4.&lt;/p&gt;
&lt;h5&gt;3. Inflate Custom View&lt;/h5&gt;
&lt;p&gt;Create a static method &lt;code&gt;make(ViewGroup parent, int duration)&lt;/code&gt;, similar to the original &lt;code&gt;Snackbar&lt;/code&gt;.&lt;code&gt;make()&lt;/code&gt; method.&lt;/p&gt;
&lt;p&gt;Here, we will inflate our custom layout, using the parent &lt;code&gt;ViewGroup&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static CustomSnackbar make(ViewGroup parent, int duration) {
       // inflate custom layout
       LayoutInflater inflater = LayoutInflater.from(parent.getContext());
       View view = inflater.inflate(R.layout.custom_snackbar, parent, false);

       // create with custom view
       ContentViewCallback callback= new ContentViewCallback(view);
       CustomSnackbar customSnackbar = new CustomSnackbar(parent, view, callback);

       customSnackbar.setDuration(duration);

       return customSnackbar;
   }
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;4. Display it&lt;/h5&gt;
&lt;p&gt;Finally, you can display your &lt;em&gt;CustomSnackbar&lt;/em&gt;, just like you would with a regular &lt;code&gt;Snackbar&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CustomSnackbar customSnackbar = CustomSnackbar.make(rootView, CustomSnackbar.LENGTH_SHORT);
       customSnackbar.setText(&quot;Your message here&quot;);
       customSnackbar.setAction(&quot;Action&quot;, new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               // TODO: handle click here
           }
       });
       customSnackbar.show();
&lt;/code&gt;&lt;/pre&gt;
&lt;h6&gt;CustomSnackbar.java&lt;/h6&gt;
&lt;p&gt;Here’s the complete code for the &lt;em&gt;CustomSnackbar&lt;/em&gt; class.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public final class CustomSnackbar
        extends BaseTransientBottomBar&amp;lt;CustomSnackbar&amp;gt; {

    protected CustomSnackbar(@NonNull ViewGroup parent, @NonNull View content, @NonNull ContentViewCallback contentViewCallback) {
        super(parent, content, contentViewCallback);
    }

    public static CustomSnackbar make(ViewGroup parent, int duration) {
        // inflate custom layout
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View view = inflater.inflate(R.layout.custom_snackbar, parent, false);

        // create with custom view
        ContentViewCallback callback= new ContentViewCallback(view);
        CustomSnackbar customSnackbar = new CustomSnackbar(parent, view, callback);
        customSnackbar.setDuration(duration);

        return customSnackbar;
    }

    private static class ContentViewCallback
            implements BaseTransientBottomBar.ContentViewCallback {

        // view inflated from custom layout
        private View view;

        public ContentViewCallback(View view) {this.view = view;}

        @Override
        public void animateContentIn(int delay, int duration) {// TODO: handle enter animation}

        @Override
        public void animateContentOut(int delay, int duration) {// TODO: handle exit animation}
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Do’s and Don&apos;ts&lt;/h4&gt;
&lt;p&gt;Knowing how to use &lt;code&gt;Snackbar&lt;/code&gt; is essential. But knowing when to use it is important as well. So before we call this a wrap, let&apos;s look at some do&apos;s and don&apos;ts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Do&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;keep the text content short&lt;/li&gt;
&lt;li&gt;Allow undoable actions to be undone (delete, archive, etc.)&lt;/li&gt;
&lt;li&gt;display feedback results for user actions&lt;/li&gt;
&lt;li&gt;style it to match your design&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Don’t&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;include icons&lt;/li&gt;
&lt;li&gt;perform core functionality via the action button&lt;/li&gt;
&lt;li&gt;display multiple instances&lt;/li&gt;
&lt;li&gt;display important system information or errors&lt;/li&gt;
&lt;li&gt;overlap or block the FAB (Floating Action Button)&lt;/li&gt;
&lt;li&gt;animate or reposition&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;Snackbar&lt;/code&gt; is comparatively a tiny component in the Material Design spec. Hence it is easily prone to misunderstanding and misuse.&lt;/p&gt;
&lt;p&gt;Giving users feedback is important. Effectively using it is key to your app.&lt;/p&gt;
&lt;h4&gt;Quick Recap&lt;/h4&gt;
&lt;p&gt;First, we clarified the difference between a &lt;code&gt;Snackbar&lt;/code&gt; and Toast. Then we even discussed when to use what.&lt;/p&gt;
&lt;p&gt;Next, we looked into using a simple implementation and went onto adding actions. From there, we looked into styling and customization options.&lt;/p&gt;
&lt;p&gt;Additionally, we saw that even a custom layout can be used. Finally, we reinforced key guidelines.&lt;/p&gt;
&lt;h5&gt;Where to from here?&lt;/h5&gt;
&lt;p&gt;This is just one of the many new additions to Material Design.&lt;/p&gt;
&lt;p&gt;The Design Support Library is making life easy for Android Developers to use Material Design. Are you using it?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Read:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/toolbar-animation-with-android-design-support-library/&quot;&gt;Flexible Space with Image pattern using Toolbar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/parallax-scrolling-tabs-design-support-library/&quot;&gt;Parallax Scrolling Effect with Header Image and Tabs&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I hope this article instilled a complete understanding about &lt;code&gt;Snackbar&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Lastly, I’d like to hear your thoughts. Have anything to add to this? Or have I missed out anything? Drop ‘em in the comments below.&lt;/p&gt;
&lt;p&gt;If you liked reading this article, share it on social media!&lt;/p&gt;
</content:encoded></item><item><title>Android Pagination: Error Handling</title><link>https://blog.iamsuleiman.com/android-pagination-error-handling/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/android-pagination-error-handling/</guid><description>Endless or Infinite scrolling is called pagination. You do this in Android using RecyclerView. However, there are a few critical error scenarios to ha</description><pubDate>Mon, 09 Jan 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Endless or Infinite scrolling is called pagination. You do this in Android using RecyclerView. However, there are a few critical error scenarios to handle.&lt;/p&gt;
&lt;p&gt;This is the third post in the Android Pagination article series.&lt;/p&gt;
&lt;p&gt;In the previous article, (&lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-recyclerview-tutorial-api-retrofit-gson/&quot;&gt;Android Pagination: Using APIs with Retrofit and Gson&lt;/a&gt;), we fetched real API data in Pagination. We used &lt;a href=&quot;http://themoviedb.org&quot;&gt;themoviedb.org&lt;/a&gt; for our data source. Additionally, &lt;a href=&quot;https://square.github.io/retrofit/&quot;&gt;Retrofit&lt;/a&gt; was used for networking, &lt;a href=&quot;https://github.com/bumptech/glide&quot;&gt;Glide&lt;/a&gt; for image loading and &lt;a href=&quot;https://github.com/google/gson&quot;&gt;Gson&lt;/a&gt; for JSON parsing.&lt;/p&gt;
&lt;p&gt;However, when networking is involved, one simply cannot ignore the various errors that occur. A good app intelligently handles all errors. This article aimed towards that.&lt;/p&gt;
&lt;p&gt;This article has been updated for AndroidX!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pagination Series Overview&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-tutorial-getting-started-recyclerview/&quot;&gt;Android Pagination Tutorial: Getting Started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-recyclerview-tutorial-api-retrofit-gson/&quot;&gt;Using APIs with Retrofit and Gson&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Error Handling&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-tutorial-recyclerview-multiple-view-types/&quot;&gt;Using Multiple RecyclerView Types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-tutorial-swipe-to-refresh/&quot;&gt;Adding Swipe-to-Refresh Support&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;p&gt;Unlike one-off API calls, which involve one request to display data on-screen, Pagination is different.&lt;/p&gt;
&lt;p&gt;Those who’ve followed my Pagination post series, know that the first-page call happens separately. This means error handling for page 1 will be different than that for page 2 and beyond.&lt;/p&gt;
&lt;p&gt;Pagination involves 2 crucial error handling scenarios. Let&apos;s deal with both.&lt;/p&gt;
&lt;h2&gt;Pagination Error Handling for Page 1&lt;/h2&gt;
&lt;p&gt;For pagination, page 1 is our one-off API call.&lt;/p&gt;
&lt;p&gt;Now if the API call fails here, the screen will be empty with nothing to display. So unless you have cached data as a backup, you have nothing to show.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/android-pagination-error-handling/one_off_loading_content.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;One-off loading content&lt;/p&gt;
&lt;p&gt;So what can we do? Use the entire screen to tell people what went wrong.&lt;/p&gt;
&lt;p&gt;Ideally, stick to a crisp one or two liner about the error. Nothing too technical. Also, don’t forget to include a ‘Call-to-Action’ (CTA) button.&lt;/p&gt;
&lt;p&gt;Mostly, the CTA would and should be a &lt;em&gt;retry button&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Here’s how I’ve modified my existing screen to accommodate an error layout:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;activity_main.xml&lt;/em&gt; layout skeleton&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;FrameLayout&amp;gt;
    &amp;lt;androidx.recyclerview.widget.RecyclerView /&amp;gt;
    &amp;lt;ProgressBar/&amp;gt;
    &amp;lt;include layout=&quot;@layout/error_layout&quot;/&amp;gt;
&amp;lt;/FrameLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;error_layout.xml&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;merge
       android:layout_width=&quot;match_parent&quot;
       android:layout_height=&quot;match_parent&quot;&amp;gt;

    &amp;lt;LinearLayout
        android:id=&quot;@+id/error_layout&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_gravity=&quot;center&quot;
        android:orientation=&quot;vertical&quot;
        android:visibility=&quot;gone&quot;
        tools:visibility=&quot;visible&quot;&amp;gt;

        &amp;lt;!--Displays a generic error message--&amp;gt;
        &amp;lt;TextView
            style=&quot;@style/TextAppearance.AppCompat.Subhead&quot;
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            android:text=&quot;@string/error_msg&quot;/&amp;gt;

  &amp;lt;!--Displays a reason for the error—&amp;gt;
        &amp;lt;TextView
            android:id=&quot;@+id/error_txt_cause&quot;
            style=&quot;@style/TextAppearance.AppCompat.Caption&quot;
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            android:layout_gravity=&quot;center&quot;
            android:layout_marginTop=&quot;@dimen/activity_margin_quarter&quot;
            tools:text=&quot;The server took too long to respond.&quot;/&amp;gt;

        &amp;lt;!—CTA— prompting user to retry failed request&amp;gt;
        &amp;lt;Button
            android:id=&quot;@+id/error_btn_retry&quot;
            style=&quot;@style/Widget.AppCompat.Button.Borderless&quot;
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            android:layout_gravity=&quot;center_horizontal&quot;
            android:layout_marginTop=&quot;@dimen/activity_margin_content&quot;
            android:text=&quot;@string/btn_retry&quot;
            android:textColor=&quot;@color/colorPrimary&quot;/&amp;gt;

    &amp;lt;/LinearLayout&amp;gt;
&amp;lt;/merge&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./android-pagination-error-handling/layout-pagination-errorview.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;One-off API call error layout&lt;/p&gt;
&lt;h3&gt;Use humor to reduce the  seriousness of the error&lt;/h3&gt;
&lt;p&gt;While this is the bare minimum, use the available screen estate effectively. Use this opportunity to display an image associated with the error. Even better if you can use a short GIF to go with it.&lt;/p&gt;
&lt;p&gt;Some examples from &lt;a href=&quot;https://material.uplabs.com/&quot;&gt;material.uplabs.com&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://material.uplabs.com/benbreckler&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Google Playbook – Error Animation by &lt;a href=&quot;https://material.uplabs.com/benbreckler&quot;&gt;Ben Breckler&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://material.uplabs.com/amit_design&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Error Screen by &lt;a href=&quot;https://material.uplabs.com/amit_design&quot;&gt;Amit Nanda&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Remember, adding a bit of humor goes a long way. But this may offend a few, so use it sparingly.&lt;/p&gt;
&lt;h3&gt;Handling Failure&lt;/h3&gt;
&lt;p&gt;Once the call fails, we must do three things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Hide the &lt;code&gt;ProgressBar&lt;/code&gt; (loading indicator)&lt;/li&gt;
&lt;li&gt;Display error layout&lt;/li&gt;
&lt;li&gt;Show the appropriate error message&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We can handle all of this by writing a convenient method &lt;code&gt;showErrorView(Throwable t)&lt;/code&gt; called in &lt;code&gt;onFailure()&lt;/code&gt; of our API call.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;callTopRatedMoviesApi().enqueue(new Callback &amp;lt; TopRatedMovies &amp;gt; () {
 @Override
 public void onResponse(Call &amp;lt; TopRatedMovies &amp;gt; call, Response &amp;lt; TopRatedMovies &amp;gt; response) {
  hideErrorView();
  // TODO: handle data
 }

 @Override
 public void onFailure(Call &amp;lt; TopRatedMovies &amp;gt; call, Throwable t) {
  t.printStackTrace();
  showErrorView(t);
 }
});

private void showErrorView(Throwable throwable) {
 if (errorLayout.getVisibility() == View.GONE) {
  errorLayout.setVisibility(View.VISIBLE);
  progressBar.setVisibility(View.GONE);

  // display appropriate error message
  // Handling 3 generic fail cases.
  if (!isNetworkConnected()) {
   txtError.setText(R.string.error_msg_no_internet);
  } else {
   if (throwable instanceof TimeoutException) {
    txtError.setText(R.string.error_msg_timeout);
   } else {
    txtError.setText(R.string.error_msg_unknown);
   }
  }
 }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;showErrorView()&lt;/code&gt; takes a &lt;code&gt;Throwable&lt;/code&gt; parameter, that can be used to know what the error is.&lt;/p&gt;
&lt;p&gt;Notice our error layout has a retry button. This is our CTA which effectively allows retrying the failed request. So hopefully our screen will have something to show now.&lt;/p&gt;
&lt;p&gt;Next, let’s add a click listener.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;btnRetry.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view {
     loadFirstPage();
   }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The button allows users to retry the first request if it failed.&lt;/p&gt;
&lt;p&gt;Let’s run through a quick recap of what we just did. We:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;modified our &lt;em&gt;activity_main.xml&lt;/em&gt; layout to include an error view&lt;/li&gt;
&lt;li&gt;displayed error view whenever the one-off API call failed&lt;/li&gt;
&lt;li&gt;used &lt;code&gt;onFailure()&lt;/code&gt; to display an appropriate error message&lt;/li&gt;
&lt;li&gt;allowed users to retry the request after failure, via a CTA (Retry &lt;code&gt;Button&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;Pagination Error Handling for Page 2 and above&lt;/h2&gt;
&lt;p&gt;As mentioned earlier, errors for Page 2 and above will be handled differently. Initially, when expecting a page to load, a &lt;code&gt;ProgressBar&lt;/code&gt; (loading indicator) is display at the footer.&lt;/p&gt;
&lt;p&gt;If the API successfully returns a response, then we remove our &lt;code&gt;ProgressBar&lt;/code&gt; and append the new data. However, for some reason, if that fails, we need to handle it.&lt;/p&gt;
&lt;p&gt;Similar to page 1, we need to do two things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Hide the footer &lt;code&gt;ProgressBar&lt;/code&gt; and show an error (in the footer) instead&lt;/li&gt;
&lt;li&gt;Tell the user what went wrong&lt;/li&gt;
&lt;li&gt;Allow them to retry&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;While the steps to perform remain the same, the key difference lies in executing this and displaying it to the user.&lt;/p&gt;
&lt;p&gt;Open &lt;em&gt;item_progress.xml&lt;/em&gt;. We need to add an error layout to this.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;FrameLayout android:layout_width=&quot;match_parent&quot;
             android:layout_height=&quot;wrap_content&quot;&amp;gt;

    &amp;lt;ProgressBar
        android:id=&quot;@+id/loadmore_progress&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_gravity=&quot;center&quot;/&amp;gt;

    &amp;lt;LinearLayout
        android:id=&quot;@+id/loadmore_errorlayout&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;match_parent&quot;
        android:background=&quot;?attr/selectableItemBackground&quot;
        android:clickable=&quot;true&quot;
        android:orientation=&quot;horizontal&quot;
        android:paddingBottom=&quot;@dimen/activity_margin&quot;
        android:paddingTop=&quot;@dimen/activity_margin&quot;
        android:visibility=&quot;gone&quot;&amp;gt;

        &amp;lt;ImageButton
            android:id=&quot;@+id/loadmore_retry&quot;
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            android:layout_gravity=&quot;center&quot;
            android:layout_marginLeft=&quot;@dimen/activity_margin_content&quot;
            android:layout_marginStart=&quot;@dimen/activity_margin_content&quot;
            android:background=&quot;@drawable/rety_selector&quot;
            android:padding=&quot;@dimen/activity_margin_half&quot;
            android:src=&quot;@drawable/ic_refresh_black_24dp&quot;
            android:tint=&quot;@color/placeholder_grey&quot;
            android:tintMode=&quot;src_in&quot;
            tools:targetApi=&quot;lollipop&quot;/&amp;gt;

        &amp;lt;LinearLayout
            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;match_parent&quot;
            android:layout_marginEnd=&quot;@dimen/activity_margin_content&quot;
            android:layout_marginLeft=&quot;@dimen/activity_margin&quot;
            android:layout_marginRight=&quot;@dimen/activity_margin_content&quot;
            android:layout_marginStart=&quot;@dimen/activity_margin&quot;
            android:gravity=&quot;center_vertical&quot;
            android:orientation=&quot;vertical&quot;&amp;gt;

            &amp;lt;TextView
                android:id=&quot;@+id/loadmore_errortxt&quot;
                style=&quot;@style/Base.TextAppearance.AppCompat.Body1&quot;
                android:layout_width=&quot;match_parent&quot;
                android:layout_height=&quot;wrap_content&quot; /&amp;gt;

            &amp;lt;TextView
                style=&quot;@style/Base.TextAppearance.AppCompat.Caption&quot;
                android:layout_width=&quot;match_parent&quot;
                android:layout_height=&quot;wrap_content&quot;
                android:text=&quot;@string/tap_to_reload&quot;/&amp;gt;

        &amp;lt;/LinearLayout&amp;gt;
    &amp;lt;/LinearLayout&amp;gt;
&amp;lt;/FrameLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./android-pagination-error-handling/layout-pagination-errorfooter.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;(Footer) Progress layout with retry UI&lt;/p&gt;
&lt;p&gt;Notice that our design now does two things. It:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;allows a user to retry&lt;/li&gt;
&lt;li&gt;tells them what went wrong&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Listening to Retry button clicks&lt;/h3&gt;
&lt;p&gt;Go to &lt;em&gt;PaginationAdapter.java&lt;/em&gt;. Let’s add the click action for the retry button.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;protected class LoadingVH extends RecyclerView.ViewHolder implements View.OnClickListener {
 private ProgressBar mProgressBar;
 private ImageButton mRetryBtn;
 private TextView mErrorTxt;
 private LinearLayout mErrorLayout;

 public LoadingVH(View itemView) {
  super(itemView);

  …
  mErrorTxt = (TextView) itemView.findViewById(R.id.loadmore_errortxt);
  mErrorLayout = (LinearLayout) itemView.findViewById(R.id.loadmore_errorlayout);

  mRetryBtn.setOnClickListener(this);
  mErrorLayout.setOnClickListener(this);
 }

 @Override
 public void onClick(View view) {
  switch (view.getId()) {
   case R.id.loadmore_retry:
   case R.id.loadmore_errorlayout:
    showRetry(false, null);
    mCallback.retryPageLoad();
    break;
  }
 }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice that &lt;code&gt;mCallback.retryPageLoad()&lt;/code&gt; is a listener which &lt;em&gt;MainActivity&lt;/em&gt; will implement.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface PaginationAdapterCallback {
 void retryPageLoad();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Head back to &lt;em&gt;MainActivity.java&lt;/em&gt; and implement the &lt;strong&gt;&lt;em&gt;PaginationAdapterCallback&lt;/em&gt;&lt;/strong&gt; interface. Then, go to the &lt;code&gt;loadNextPage()&lt;/code&gt; method and make the following changes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private void loadNextPage() {
 callTopRatedMoviesApi().enqueue(new Callback &amp;lt; TopRatedMovies &amp;gt; () {
  @Override
  public void onResponse(Call &amp;lt; TopRatedMovies &amp;gt; call,
   Response &amp;lt; TopRatedMovies &amp;gt; response) {
   adapter.removeLoadingFooter();
   isLoading = false;…
  }

  @Override
  public void onFailure(Call &amp;lt; TopRatedMovies &amp;gt; call, Throwable t) {
   adapter.showRetry(true, fetchErrorMessage(t));
  }
 });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Add the &lt;code&gt;showRetry()&lt;/code&gt; method in &lt;em&gt;PaginationAdapter.java&lt;/em&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public void showRetry(boolean show, @Nullable String errorMsg) {
 retryPageLoad = show;
 notifyItemChanged(movieResults.size() - 1);

 if (errorMsg != null) this.errorMsg = errorMsg;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;adapter.showRetry()&lt;/code&gt; is responsible for changing the footer &lt;code&gt;ProgressBar&lt;/code&gt; into a retry button. It additionally displays an error message saying what went wrong.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Displaying an error message matters&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Typically, apps tend to show a retry button on failure. They miss out on telling us what exactly went wrong. The reason for failure could be anything. Does the user have a network issue? Or did the server fail to respond?&lt;/p&gt;
&lt;p&gt;Most importantly, the error message tells us on whose side the issue is.&lt;/p&gt;
&lt;p&gt;Here is how &lt;em&gt;Instagram&lt;/em&gt; and &lt;em&gt;DailyHunt (NewsHunt)&lt;/em&gt; handle pagination errors:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-pagination-error-handling/instagram_pagination_error_handling.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Pagination error handling in Instagram&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-pagination-error-handling/dailyhunt_pagination_error_handling.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;DailyHunt pagination error handling&lt;/p&gt;
&lt;p&gt;Take a good look at both these examples. Which one do you think did a better job of telling you what went wrong? That&apos;s right, Dailyhunt. The app clearly tells us what the issue is. Also, it tells us what to do, to rectify it. Finally, the error footer is clickable, allowing us to retry that failed request.&lt;/p&gt;
&lt;p&gt;While Instagram certainly does have a clean design, simply showing a retry option doesn&apos;t really tell us the problem.&lt;/p&gt;
&lt;p&gt;Finally, with everything done, let&apos;s go ahead and run our app.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Final Results&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/S8cUHwkaXw0&quot;&gt;Watch on YouTube&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We&apos;ve now successfully handled both use cases. Page 1 is a separate call compared to the rest of the pages.&lt;/p&gt;
&lt;p&gt;When page 1 fails, we don&apos;t have any content to show the user. This leaves the entire screen blank. We handled this by smartly using the available screen estate. An appropriate error message was displayed. Additionally, we allowed users to retry the failed request.&lt;/p&gt;
&lt;p&gt;We then followed a similar approach to handle page 2 and beyond. In addition, to display a retry button in the footer, we displayed the reason for failure as well. Finally, we inferred from 2 famous apps about how they handled a similar scenario.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Suleiman19/Android-Pagination-with-RecyclerView/tree/9d375bb677963845a22eec4b6b6628ac7fac74db&quot;&gt;View &lt;strong&gt;Source Code&lt;/strong&gt; on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Some key takeaways:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pagination primarily has 2 error cases to be handled&lt;/li&gt;
&lt;li&gt;Errors can be unavoidable, but we can take steps to handle them&lt;/li&gt;
&lt;li&gt;Tell users what exactly went wrong, but don&apos;t get too technical&lt;/li&gt;
&lt;li&gt;Be forgiving with errors (consider using humor) and allow users to retry requests&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I hope this post helped make your paginated apps error-prepared.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Read next&lt;/strong&gt; – &lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-tutorial-recyclerview-multiple-view-types/&quot;&gt;Part 4: Handling multiple View Types with Pagination&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As always, I&apos;d like to hear what you think. Tell me if I covered all the use cases. Did I miss out on anything? Drop &apos;em in the comments below.&lt;/p&gt;
&lt;p&gt;I’m happy you took the time to read this. All I need for you is to help me spread the word!&lt;/p&gt;
</content:encoded></item><item><title>Android Pagination: Using APIs with Retrofit and Gson</title><link>https://blog.iamsuleiman.com/android-pagination-recyclerview-tutorial-api-retrofit-gson/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/android-pagination-recyclerview-tutorial-api-retrofit-gson/</guid><description>Let&apos;s look at Android Pagination with RecyclerView, using real data from an API. This will give us a better understanding of Pagination. First, we&apos;ll </description><pubDate>Tue, 22 Nov 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Let&apos;s look at Android Pagination with &lt;code&gt;RecyclerView&lt;/code&gt;, using real data from an API. This will give us a better understanding of Pagination. First, we&apos;ll look at what API to use. Next, we will set up a networking library (Retrofit) that will help us perform these API calls.&lt;/p&gt;
&lt;p&gt;This is the second post in a series of Android Pagination articles. In the previous, &lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-tutorial-getting-started-recyclerview/&quot;&gt;Android Pagination Tutorial: Getting Started article&lt;/a&gt;, we learned about Pagination and implemented its logic. We created dummy content to populate our &lt;code&gt;RecyclerView.Adapter&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This article has been updated for AndroidX!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pagination Series Overview&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-tutorial-getting-started-recyclerview/&quot;&gt;Android Pagination Tutorial: Getting Started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Using APIs with Retrofit and Gson&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-error-handling/&quot;&gt;Error Handling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-tutorial-recyclerview-multiple-view-types/&quot;&gt;Using Multiple RecyclerView Types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-tutorial-swipe-to-refresh/&quot;&gt;Adding Swipe-to-Refresh Support&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;p&gt;In this post, we will look at fetching data from an API, as a real-time scenario. This will give us a better understanding of Android Pagination. First, we&apos;ll look at what API to use. Next, we will set up a networking library (Retrofit) that will help us perform these API calls.&lt;/p&gt;
&lt;p&gt;For a real-world scenario, we&apos;ll need real content from an API. For that, let&apos;s go with &lt;a href=&quot;https://www.themoviedb.org&quot;&gt;themoviedb.org&lt;/a&gt;(TMDb). A popular, user-maintained database for movies and TV shows.&lt;/p&gt;
&lt;h2&gt;The Movie DB API&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./android-pagination-recyclerview-tutorial-api-retrofit-gson/themoviedb-home-page.png&quot; alt=&quot;themoviedb.org&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://themoviedb.org&quot;&gt;themoviedb.org&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We need an API key before we can start using their APIs. So go ahead and &lt;a href=&quot;https://www.themoviedb.org/account/signup&quot;&gt;sign up&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Next, login in and go to your account. Generate an API key from there. Be advised, there&apos;s a fairly long form you need to fill. The API is free, so the least we can do is fill a form. So do swift of that, and get your key.&lt;br /&gt;
After that, either go through their documentation for in-depth usage. Otherwise, for the scope of this tutorial, we&apos;ll simply make a request to find &apos;top rated movies&apos;. You could use a URL of your own choice, or follow along with me.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;API Call for Top Rated Movies&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Here&apos;s the shortest URL we need:&lt;/p&gt;
&lt;p&gt;_&lt;a href=&quot;https://api.themoviedb.org/3/movie/top_rated?api_key=YOUR_API_KEY&amp;amp;language=en-US&amp;amp;page=1_&quot;&gt;https://api.themoviedb.org/3/movie/top_rated?api_key=YOUR_API_KEY&amp;amp;language=en-US&amp;amp;page=1_&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Just remember to replace &lt;strong&gt;&lt;em&gt;YOUR_API_KEY&lt;/em&gt;&lt;/strong&gt; with your actual API key!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;JSON Response for Top Rated Movies&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;{
&quot;page&quot;: 1,
&quot;results&quot;: [
{
&quot;poster_path&quot;: &quot;\/9O7gLzmreU0nGkIB6K3BsJbzvNv.jpg&quot;,
&quot;adult&quot;: false,
&quot;overview&quot;: &quot;Framed in the 1940s for the double murder of his wife and her lover, upstanding banker...&quot;,
&quot;release_date&quot;: &quot;1994-09-10&quot;,
&quot;genre_ids&quot;: [
18,
80
],
&quot;id&quot;: 278,
&quot;original_title&quot;: &quot;The Shawshank Redemption&quot;,
&quot;original_language&quot;: &quot;en&quot;,
&quot;title&quot;: &quot;The Shawshank Redemption&quot;,
&quot;backdrop_path&quot;: &quot;\/xBKGJQsAIeweesB79KC89FpBrVr.jpg&quot;,
&quot;popularity&quot;: 8.522754,
&quot;vote_count&quot;: 5493,
&quot;video&quot;: false,
&quot;vote_average&quot;: 8.34
},
… // Other result (movie) objects
],
&quot;total_results&quot;: 4341,
&quot;total_pages&quot;: 218
}&lt;/p&gt;
&lt;p&gt;Notice the &lt;code&gt;page&lt;/code&gt; attribute in the response. It starts at 1. We also get a nice response that tells us the &lt;code&gt;total_pages&lt;/code&gt; is 218. That means we can Pagination 218 times in total, with about 20 content per page! However, we don&apos;t need that much, so for this tutorial, let&apos;s stick to 5 pages in total?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TIP:&lt;/strong&gt;&lt;br /&gt;
I recommend using &lt;a href=&quot;https://www.getpostman.com/&quot;&gt;Postman&lt;/a&gt; when dealing with APIs. It gives you a clear idea of how to construct proper API requests. Also, the formatted JSON response is handy too.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Before we begin, we&apos;ll need to decide upon a networking library (and image loading library too, if you wish). Dealing with text and media in APIs is pretty common, so I&apos;ll assume we need both. These libraries will do most of the heavy-lifting, allowing us to focus on the app itself.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tech Stack:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.themoviedb.org/account/signup&quot;&gt;Gson&lt;/a&gt; - library to convert Java Objects into their JSON representation and back&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/square/retrofit&quot;&gt;Retrofit&lt;/a&gt; - HTTP client for Android&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/bumptech/glide&quot;&gt;Glide&lt;/a&gt; - image loading and caching library for Android; handy for smooth scrolling&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You might be familiar with Retrofit and Gson. They&apos;re a powerful combination, often preferred when dealing with APIs. The CodePath guides is a perfect place to start for the uninitiated:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://guides.codepath.com/android/Consuming-APIs-with-Retrofit&quot;&gt;Consuming APIs with Retrofit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://guides.codepath.com/android/Leveraging-the-Gson-Library&quot;&gt;Leveraging the Gson Library&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, not to worry if you&apos;re unfamiliar with them. I&apos;ll be going over the basics. Just enough to get your app working!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Also Read:&lt;/strong&gt; &lt;a href=&quot;https://blog.iamsuleiman.com/android-sqlite-database-tutorial-sugar-orm/&quot;&gt;Create an Image Gallery Android App with Sugar ORM and Glide&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;Start by adding Gson, Retrofit, and Glide to your &lt;em&gt;&lt;strong&gt;app/build.gradle&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ext {
    retrofit = &apos;2.6.1&apos;
    axAppcompat = &apos;1.0.2&apos;
    axOthers = &apos;1.0.0&apos;
    glide = &apos;4.9.0&apos;
    supportLib= &apos;28.0.0&apos;
}

  /*
        TODO: remove temporary fix for Glide compiler issue
        https://github.com/bumptech/glide/issues/3185
      */

    // Temporary fix begin
    implementation &quot;com.android.support:support-annotations:${supportLib}&quot;
    annotationProcessor &quot;com.android.support:support-annotations:${supportLib}&quot;
    // Temporary fix end

    implementation &quot;com.squareup.retrofit2:retrofit:${retrofit}&quot;
    implementation &quot;com.squareup.retrofit2:converter-gson:${retrofit}&quot;
    implementation (&quot;com.github.bumptech.glide:glide:$glide&quot;) {
        exclude group: &quot;com.android.support&quot;
    }
    annotationProcessor &quot;com.github.bumptech.glide:compiler:$glide&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
You might notice that I&apos;ve added Android&apos;s Support libraries while I&apos;m also using AndroidX. This is a temporary workaround that&apos;s needed because currently, Glide&apos;s annotation processor has only partial support for AndroidX. In other words, this won&apos;t break anything since I&apos;ve tested it for you. Simply copy paste these dependencies and you should be good.&lt;/p&gt;
&lt;p&gt;Additionally, we need a Gson converter for Retrofit. It allows serializing JSON responses to model classes using Gson, automagically! This allows us to work with data, via models. So, no more manual JSON parsing!&lt;/p&gt;
&lt;p&gt;Don&apos;t forget to add internet permissions in &lt;em&gt;AndroidManifest.xml&lt;/em&gt;!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;uses-permission android:name=&quot;android.permission.INTERNET&quot;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;br /&gt;
This is not a tutorial about using Retrofit. However, I will go through the bare minimum that’s required to set up Retrofit and use it.&lt;/p&gt;
&lt;h3&gt;Preparing Model Classes with Gson&lt;/h3&gt;
&lt;p&gt;We need to create model classes that mirror our API response. While you can take your time to manually create this, I want to automate it. We already know &lt;a href=&quot;#response&quot;&gt;how our API response looks like&lt;/a&gt;. So let&apos;s auto-generate our model classes and save ourselves time.&lt;/p&gt;
&lt;p&gt;Head over to &lt;a href=&quot;http://www.jsonschema2pojo.org&quot;&gt;http://www.jsonschema2pojo.org&lt;/a&gt; and paste your API response. Set the parameters on the right as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Set the (project) package name and parent model class name (ideally should be the name of the API call, i.e. TopRatedMovies)&lt;/li&gt;
&lt;li&gt;Set Source Type as JSON&lt;/li&gt;
&lt;li&gt;Set Annotation Style as GSON&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Finally, hit Zip to generate the class files and download them. Or, you can &lt;a href=&quot;https://github.com/Suleiman19/Android-Pagination-with-RecyclerView/tree/master/app/src/main/java/com/suleiman/pagination/models&quot;&gt;get the files directly from me&lt;/a&gt;. :)&lt;/p&gt;
&lt;p&gt;Let&apos;s take a quick breather here. Did you just see what we did? We auto-generated all the model classes we need to handle a particular API response. Just how amazing is that!?&lt;/p&gt;
&lt;p&gt;Either way, you&apos;ll end up with two model classes. Parent model &lt;em&gt;&lt;strong&gt;TopRatedMovies&lt;/strong&gt;&lt;/em&gt; and the other model is automatically named &lt;em&gt;&lt;strong&gt;Result&lt;/strong&gt;&lt;/em&gt;. Notice how each model&apos;s property is annotated to its JSON response attribute. Gson uses these annotations to map the JSON values to its respective model properties.&lt;/p&gt;
&lt;p&gt;With this done, we can proceed to set up Retrofit.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Modifying PaginationAdapter&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Compare the API response with our model classes. Each movie object in the array is &lt;em&gt;Result.java&lt;/em&gt;, and the entire response is &lt;em&gt;TopRaterMovies.java&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Also, consecutive page requests indicate multiple &lt;em&gt;TopRatedMovies&lt;/em&gt; model. This implies that our &lt;code&gt;RecyclerView.Adapter&lt;/code&gt; must use &lt;code&gt;List&amp;lt;TopRatedMovies&amp;gt;&lt;/code&gt;. So go ahead and modify &lt;em&gt;PaginationAdapter&lt;/em&gt; to use the same.&lt;/p&gt;
&lt;p&gt;Updated &lt;em&gt;PaginationAdapter&lt;/em&gt; can be found &lt;a href=&quot;https://github.com/Suleiman19/Android-Pagination-with-RecyclerView/blob/0fe1c54189bee46bde3cee91bd6a2be60ea252f8/app/src/main/java/com/suleiman/pagination/PaginationAdapter.java&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;br /&gt;
Delete the &lt;em&gt;Movie.java&lt;/em&gt; model class as its no longer needed.&lt;/p&gt;
&lt;h2&gt;Configuring Retrofit&lt;/h2&gt;
&lt;p&gt;Create a class &lt;em&gt;&lt;strong&gt;MovieApi.java&lt;/strong&gt;&lt;/em&gt;. This will be responsible for configuring the Retrofit client. Next, create an interface called &lt;em&gt;&lt;strong&gt;MovieService&lt;/strong&gt;&lt;/em&gt;. We will define all our API calls here. Retrofit uses Annotations to define API calls.&lt;/p&gt;
&lt;p&gt;Open &lt;em&gt;MovieApi.java&lt;/em&gt;. We&apos;ll now configure the Retrofit client.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class MovieApi {
 private static Retrofit retrofit = null;

 public static Retrofit getClient(Context context) {
  if (retrofit == null) {
   retrofit = new Retrofit.Builder()
    .addConverterFactory(GsonConverterFactory.create())
    .baseUrl(&quot;https://api.themoviedb.org/3/&quot;)
    .build();
  }
  return retrofit;
 }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;br /&gt;
Remember that the base URL must always end with a forward trailing slash.&lt;/p&gt;
&lt;p&gt;Now, head over to &lt;em&gt;MovieService.java&lt;/em&gt;. We will define our top-rated movies API call here.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Declare all your API calls here
public interface MovieService {

 @GET(&quot;top_rated&quot;)
 Call &amp;lt; TopRatedMovies &amp;gt; getTopRatedMovies(
  @Query(&quot;api_key&quot;) String apiKey,
  @Query(&quot;language&quot;) String language,
  @Query(&quot;page&quot;) int pageIndex
 );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Making API Calls with Retrofit&lt;/h3&gt;
&lt;p&gt;Go to &lt;em&gt;MainActivity&lt;/em&gt;. If you remember from &lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-tutorial-getting-started-recyclerview/&quot;&gt;Part 1 of the Android Pagination tutorial&lt;/a&gt;, there is a method called &lt;code&gt;loadFirstPage()&lt;/code&gt;. We were loading dummy data here at first. Scrap those lines off. Now we&apos;re going to perform the API request here. We&apos;ll start by requesting for the very first page, i.e. page 1.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...
@Override
protected void onCreate(Bundle savedInstanceState) {
 …
 //init service and load data
 MovieService movieService = MovieApi.getClient().create(MovieService.class); //1
 loadFirstPage();
}
/**
 * Performs a Retrofit call to the top rated movies API.
 */
private Call &amp;lt; TopRatedMovies &amp;gt; callTopRatedMoviesApi() { //2
 return movieService.getTopRatedMovies(
  getString(R.string.my_api_key),
  &quot;en_US&quot;,
  currentPage
 );
}
/*
 * Extracts List&amp;lt;Result&amp;gt; from response
 */
private List &amp;lt; Result &amp;gt; fetchResults(Response &amp;lt; TopRatedMovies &amp;gt; response) { //3
 TopRatedMovies topRatedMovies = response.body();
 return topRatedMovies.getResults();
}
private void loadFirstPage() {
 callTopRatedMoviesApi().enqueue(new Callback &amp;lt; TopRatedMovies &amp;gt; () { //4
  @Override
  public void onResponse(Call &amp;lt; TopRatedMovies &amp;gt; call, Response &amp;lt; TopRatedMovies &amp;gt; response) {

   List &amp;lt; Result &amp;gt; results = fetchResults(response); //5
   progressBar.setVisibility(View.GONE);
   adapter.addAll(results);

   if (currentPage &amp;lt;= TOTAL_PAGES) adapter.addLoadingFooter();
   else isLastPage = true;
  }

  @Override
  public void onFailure(Call &amp;lt; TopRatedMovies &amp;gt; call, Throwable t) {
   // handle error
  }
 });
}
private void loadNextPage() {
  callTopRatedMoviesApi().enqueue(new Callback &amp;lt; TopRatedMovies &amp;gt; () { //6
   @Override
   public void onResponse(Call &amp;lt; TopRatedMovies &amp;gt; call, Response &amp;lt; TopRatedMovies &amp;gt; response) {
    adapter.removeLoadingFooter();
    isLoading = false;

    List &amp;lt; Result &amp;gt; results = fetchResults(response);
    adapter.addAll(results);

    if (currentPage != TOTAL_PAGES) adapter.addLoadingFooter();
    else isLastPage = true;
   }

   @Override
   public void onFailure(Call &amp;lt; TopRatedMovies &amp;gt; call, Throwable t) {
    // handle failure
   }
  });
 }
 ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are crucial snippets of an updated &lt;em&gt;MainActivity.java&lt;/em&gt;. Let&apos;s go over what each of the commented steps means.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Start by initializing &lt;em&gt;MovieService&lt;/em&gt; object with a Retrofit instance. Look at &lt;code&gt;getClient()&lt;/code&gt; method in &lt;em&gt;MovieApi.java&lt;/em&gt;, you&apos;ll notice that it builds a configured Retrofit instance.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;callTopRatedMoviesApi()&lt;/code&gt; returns the Retrofit API call since we&apos;ll be reusing the same. The method parameters passed here are query parameters for the API&apos;s URL.&lt;/li&gt;
&lt;li&gt;Another helper method that extracts the list of results (movies) from the API response.&lt;/li&gt;
&lt;li&gt;Attach an API callback using &lt;code&gt;enqueue()&lt;/code&gt; to handle the response.&lt;/li&gt;
&lt;li&gt;Notice how the callback returns &lt;code&gt;Response&amp;lt;TopRatedMovies&amp;gt;&lt;/code&gt; and not a generic JSON String. This is the magic of Gson. It serialized the entire response into &lt;em&gt;TopRatedMovies&lt;/em&gt;. However, what we actually need is a list of movies gives by &lt;code&gt;List&amp;lt;Results&amp;gt;&lt;/code&gt; from &lt;em&gt;TopRatedMovies&lt;/em&gt; class.&lt;/li&gt;
&lt;li&gt;We use the same API call for loading the next page too. &lt;code&gt;mCurrentPage&lt;/code&gt; is incremented by &lt;em&gt;PaginationScrollListener&lt;/em&gt;, so the API loads the indicated page number&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you noticed back in the API response, Pagination starts from page 1. There is no index zero. Hence change &lt;code&gt;PAGE_START = 1.&lt;/code&gt; Additionally, the response includes other useful information such as up to how many pages we can paginate.&lt;/p&gt;
&lt;h3&gt;Updating PaginationAdapter to display API data&lt;/h3&gt;
&lt;p&gt;Now, we have a working API call with a response, so head over to &lt;em&gt;PaginationAdapter&lt;/em&gt;. First, we start by updating our helper methods. If you can recall, we had defined the following methods in Part 1:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;void add(Result r)
void addAll(List&amp;lt;Result&amp;gt; moveResults)
void remove(Result r) 
void clear()
boolean isEmpty()
void addLoadingFooter()
void removeLoadingFooter()
Result getItem(int position)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
We don&apos;t use the &lt;em&gt;Movie&lt;/em&gt; model class anymore. Instead our &apos;Movie&apos; object is now replaced by &lt;em&gt;Result.java&lt;/em&gt;. So update your methods accordingly!&lt;/p&gt;
&lt;p&gt;Next, our list of data will now become a &lt;code&gt;List&amp;lt;Result&amp;gt;&lt;/code&gt; object. So change that in your adapter as well, if you haven&apos;t.&lt;/p&gt;
&lt;p&gt;With that done, the last step is to update &lt;code&gt;onBindViewHolder()&lt;/code&gt; with our new data.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

 Result result = movieResults.get(position); // Movie

 switch (getItemViewType(position)) {
  case ITEM:
   final MovieVH movieVH = (MovieVH) holder;

   movieVH.mMovieTitle.setText(result.getTitle());

   movieVH.mYear.setText(
    result.getReleaseDate().substring(0, 4) // we want the year alone
    +
    &quot; | &quot; +
    result.getOriginalLanguage().toUpperCase()
   );

   movieVH.mMovieDesc.setText(result.getOverview());

   // Using Glide to handle image loading.
   Glide
    .with(context)
    .load(BASE_URL_IMG + result.getPosterPath())
    .listener(new RequestListener &amp;lt; String, GlideDrawable &amp;gt; () {
     @Override
     public boolean onException(Exception e, String model, Target &amp;lt; GlideDrawable &amp;gt; target, boolean isFirstResource) {
      // handle failure
      movieVH.mProgress.setVisibility(View.GONE);
      return false;
     }

     @Override
     public boolean onResourceReady(GlideDrawable resource, String model, Target &amp;lt; GlideDrawable &amp;gt; target, boolean isFromMemoryCache, boolean isFirstResource) {
      // image ready, hide progress now
      movieVH.mProgress.setVisibility(View.GONE);
      return false; // return false if you want Glide to handle everything else.
     }
    })
    .diskCacheStrategy(DiskCacheStrategy.ALL) // cache both original &amp;amp; resized image
    .centerCrop()
    .crossFade()
    .into(movieVH.mPosterImg);

   break;

  case LOADING:
   //                Do nothing
   break;
 }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;
Don&apos;t forget to update your &lt;code&gt;ViewHolder&lt;/code&gt; item layout accordingly. For example, here&apos;s how I&apos;ve modified mine to display the new data. However I&apos;m sure you can come up with something better!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-pagination-recyclerview-tutorial-api-retrofit-gson/pagination_list_item.png&quot; alt=&quot;pagination_list_item&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Adapter item layout&lt;/p&gt;
&lt;h3&gt;BONUS - Automatically Log Network Calls&lt;/h3&gt;
&lt;p&gt;With Retrofit, it might be a little difficult to manually log network responses. Since Gson maps it to our model classes, getting back the JSON is difficult. As trying to deserialize an already serialized response, defeats the purpose of using Gson in the first place. So what can we do?&lt;/p&gt;
&lt;p&gt;Retrofit plays nicely with &lt;a href=&quot;http://square.github.io/okhttp/&quot;&gt;OkHttp&lt;/a&gt;, an efficient HTTP client for Android and Java. By using &lt;code&gt;Interceptors&lt;/code&gt;, OkHttp allows us to &apos;intervene&apos; between network calls and perform our desired action.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Interceptors are a powerful mechanism that can monitor, rewrite, and retry calls - &lt;a href=&quot;https://github.com/square/okhttp/wiki/Interceptors&quot;&gt;OkHttp Wiki&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A popular use case for Intercepters would be to append our API key as a query parameter to every request. This sure beats manually passing it as a method parameter to each request.&lt;/p&gt;
&lt;p&gt;Coming back to automatic logging, we will be using the very same &lt;code&gt;Interceptor&lt;/code&gt; to get our job done.&lt;/p&gt;
&lt;p&gt;Add the following library to your &lt;em&gt;app/&lt;strong&gt;build.gradle&lt;/strong&gt;&lt;/em&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;implementation &apos;com.squareup.okhttp3:logging-interceptor:4.0.1&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, open &lt;em&gt;MovieApi.java&lt;/em&gt; and modify the &lt;code&gt;getClient()&lt;/code&gt; method as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// builds OkHttpClient with logging Interceptor  
 private static OkHttpClient buildClient() {
  return new OkHttpClient
   .Builder()
   .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
   .build();
 }
 public static Retrofit getClient() {
  if (retrofit == null) {
   retrofit = new Retrofit.Builder()
    .client(buildClient())
    .addConverterFactory(GsonConverterFactory.create())
    .baseUrl(&quot;https://api.themoviedb.org/3/&quot;)
    .build();
  }
  return retrofit;
 }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The highlighted line emphasizes how the custom client is attached to the Retrofit builder. You can use the &lt;code&gt;buildClient()&lt;/code&gt; method to add yet another Interceptor if you wish.&lt;/p&gt;
&lt;p&gt;Run your app now and you&apos;ll observe that your network activity is now automatically logged. You can even find the raw JSON response there. Cheers!&lt;/p&gt;
&lt;p&gt;The complete project with auto logging is available in commit &quot;&lt;em&gt;auto logging network calls&lt;/em&gt;&quot;.You can see the &lt;a href=&quot;https://github.com/Suleiman19/Android-Pagination-with-RecyclerView/tree/0f2529c418daeb5c4ccb68735cb5a9ef36a11745&quot;&gt;source code that contains auto-logging network calls&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Output&lt;/h2&gt;
&lt;p&gt;Now that we&apos;ve done everything needed, go ahead and run your app. Here&apos;s how the output should look like:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/android-pagination-recyclerview-tutorial-api-retrofit-gson/pagination_2_api_op.gif&quot; alt=&quot;pagination_2_api_op&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;br /&gt;
You might notice duplicated contents at the end and the beginning of consecutive pages.  Eg: The movie &apos;Empire Strikes Back&apos;, might appear twice. This occurs twice in the paginated response and is no cause for alarm.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Project Available on GitHub&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Suleiman19/Android-Pagination-with-RecyclerView/tree/0fe1c54189bee46bde3cee91bd6a2be60ea252f8&quot;&gt;View the entire project source code&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;In this post, we were able to take Pagination and apply it to a real-world example using an API. We used Retrofit to handle our networking, Gson to maintain our model classes and auto-parse JSON results. We also used Glide to make image handling a breeze. Next, we updated our existing code to reflect the new API.&lt;/p&gt;
&lt;p&gt;However, with network and API calls in play, we cannot ignore the scenario of an API call failing. Nor can we ignore when our mobile data or Wi-Fi stops working. Error handling becomes imperative in such cases.&lt;/p&gt;
&lt;p&gt;In &lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-error-handling/&quot;&gt;Part 3&lt;/a&gt;, I&apos;ll show you how to deal with such cases.&lt;/p&gt;
</content:encoded></item><item><title>Pagination Android Tutorial with RecyclerView: Getting Started</title><link>https://blog.iamsuleiman.com/android-pagination-tutorial-getting-started-recyclerview/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/android-pagination-tutorial-getting-started-recyclerview/</guid><description>Pagination (Endless Scrolling or Infinite Scrolling) is a feature common in content-heavy apps. It breaks down a list of content into equal smaller pi</description><pubDate>Tue, 01 Nov 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Pagination (Endless Scrolling or Infinite Scrolling) is a feature common in content-heavy apps. It breaks down a list of content into equal smaller pieces, loaded one at a time.&lt;/p&gt;
&lt;p&gt;This is the first post in a series of Pagination articles. The series covers how to implement Pagination with RecyclerView, handle adapter changes with new data, error handling and more.&lt;/p&gt;
&lt;p&gt;This article has been updated for AndroidX!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pagination Series Overview&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Pagination Android Tutorial: Getting Started&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-recyclerview-tutorial-api-retrofit-gson/&quot;&gt;Using APIs with Retrofit and Gson&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-error-handling/&quot;&gt;Error Handling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-tutorial-recyclerview-multiple-view-types/&quot;&gt;Using Multiple RecyclerView Types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-tutorial-swipe-to-refresh/&quot;&gt;Adding Swipe-to-Refresh Support&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;The What, Why and When of Pagination&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Pagination&lt;/em&gt; is the process of dividing a document into discrete pages, either electronic pages or printed pages. -  &lt;a href=&quot;https://en.wikipedia.org/wiki/Pagination&quot;&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Already know what Pagination is? Jump straight to the &lt;a href=&quot;#codestart&quot;&gt;code section&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;What we&apos;re going to do, relates to this definition. Loading the next set of data (next page), by specifying its index (page number).&lt;/p&gt;
&lt;h3&gt;What is Pagination?&lt;/h3&gt;
&lt;p&gt;Users of Facebook, Twitter or Instagram will know what I&apos;m talking about. After all, we&apos;ve spent countless hours scrolling through them haven&apos;t we? They just don&apos;t seem to end!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-pagination-tutorial-getting-started-recyclerview/twitter_suleiman_194_pagination.png&quot; alt=&quot;twitter profile tweets pagination endless scroll load more&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Twitter Profile Tweets list&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why Pagination?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;From a developer&apos;s perspective, how would you load all of that content? It is not possible to make a call for such huge content at one go. We&apos;ll have to request them in parts, or &apos;pages&apos;.&lt;/p&gt;
&lt;p&gt;Pagination allows the user to see the latest content with little wait time. As we load the next &apos;page&apos; by the time users scroll to the bottom, more content is loaded and available.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When to use Pagination?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&apos;m sure you have a pretty good idea by now on when to use it. If you have a ton of content that takes too long to load. This can be either from a local database or an API call. Then it makes sense to use Pagination. If you&apos;re pulling from a database, request data in batches (say 20 per request). The same also holds true for an API call.&lt;/p&gt;
&lt;p&gt;With that out of the way, I&apos;m sure you&apos;d want to see some Android code with Pagination in action. So without further delay, let&apos;s get straight to it!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;As we all know, Pagination has been around for quite some time. This opens it up to various approaches on how exactly to do it.&lt;/p&gt;
&lt;p&gt;Here are some solutions you might have come across:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Endless Scrolling with AdapterView and &lt;code&gt;RecyclerView&lt;/code&gt; - &lt;a href=&quot;https://guides.codepath.com/android/Endless-Scrolling-with-AdapterViews-and-RecyclerView&quot;&gt;guides.codepath.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;How to implement an endless list with &lt;code&gt;RecyclerView&lt;/code&gt; - &lt;a href=&quot;http://stackoverflow.com/questions/26543131/how-to-implement-endless-list-with-recyclerview&quot;&gt;stackoverflow.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But these don’t tell you how to show or hide a footer loading progress (&lt;code&gt;ProgressBar&lt;/code&gt;). You also would have resorted to an Android Pagination library on GitHub:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/MarkoMilos/Paginate&quot;&gt;Paginate by MarkoMilos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/MarkoMilos/Paginate&quot;&gt;SuperRecyclerView by Malinskiy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usually, I’d suggest one of the above, but this time I won&apos;t. That&apos;s because we can roll our own scroll listener. This would be simpler instead. Sometimes it&apos;s better to be in control of our feature, especially when third party solutions refuse to work the way you want.&lt;/p&gt;
&lt;h3&gt;Android Pagination with RecyclerView&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Custom OnScrollListener&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public abstract class PaginationScrollListener extends RecyclerView.OnScrollListener {

 LinearLayoutManager layoutManager;

 public PaginationScrollListener(LinearLayoutManager layoutManager) {
  this.layoutManager = layoutManager;
 }

 @Override
 public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
  super.onScrolled(recyclerView, dx, dy);

  int visibleItemCount = layoutManager.getChildCount();
  int totalItemCount = layoutManager.getItemCount();
  int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition();

  if (!isLoading() &amp;amp;&amp;amp; !isLastPage()) {
   if ((visibleItemCount + firstVisibleItemPosition) &amp;gt;=
    totalItemCount &amp;amp;&amp;amp; firstVisibleItemPosition &amp;gt;= 0) {
    loadMoreItems();
   }
  }
 }

 protected abstract void loadMoreItems();
 public abstract int getTotalPageCount();
 public abstract boolean isLastPage();
 public abstract boolean isLoading();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Copy over this class. To enable Pagination, we must detect the user reaching the end of the list (&lt;code&gt;RecyclerView&lt;/code&gt;). &lt;strong&gt;&lt;em&gt;PaginationScrollListener&lt;/em&gt;&lt;/strong&gt; allows us to do so.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt;&lt;br /&gt;
The &lt;code&gt;onScrolled()&lt;/code&gt; logic is the most important piece of your entire Pagination logic. So make sure you&apos;re doing it right. The key snippet which contains the Pagination logic is as follows.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (!isLoading() &amp;amp;&amp;amp; !isLastPage()) {
 if ((visibleItemCount + firstVisibleItemPosition) &amp;gt;=
  totalItemCount &amp;amp;&amp;amp; firstVisibleItemPosition &amp;gt;= 0) {
  loadMoreItems();
 }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Layout Setup&lt;/h4&gt;
&lt;p&gt;Create a layout with &lt;code&gt;RecyclerView&lt;/code&gt; and a &lt;code&gt;ProgressBar&lt;/code&gt; (for indicating load of initial content).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// activity_main.xml skeleton layout

&amp;lt;FrameLayout&amp;gt; 
    &amp;lt;androidx.recyclerview.widget.RecyclerView /&amp;gt; 
    &amp;lt;ProgressBar android:layout_gravity=&quot;center”/&amp;gt; 
&amp;lt;/FrameLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Creating RecyclerView.Adapter&lt;/h4&gt;
&lt;p&gt;First, create class &lt;em&gt;PaginationAdapter&lt;/em&gt; extending &lt;code&gt;RecyclerView.Adapter&lt;/code&gt;, and then create two &lt;code&gt;RecyclerView.ViewHolder&lt;/code&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;class &lt;code&gt;ContentVH&lt;/code&gt; (main content item)&lt;/li&gt;
&lt;li&gt;class &lt;code&gt;LoadingVH&lt;/code&gt; (footer ProgressBar used for Pagination)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I will be going through the essentials of the adapter, as creating a regular &lt;code&gt;RecyclerView.Adapter&lt;/code&gt; is quite common by now.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class PaginationAdapter extends RecyclerView.Adapter &amp;lt; RecyclerView.ViewHolder &amp;gt; {

 // flag for footer ProgressBar (i.e. last item of list)
 private boolean isLoadingAdded = false;
 ...
 @Override
 public int getItemCount() {
  return movies == null ? 0 : movies.size();
 }
 @Override
 public int getItemViewType(int position) {
  return (position == movies.size() - 1 &amp;amp;&amp;amp; isLoadingAdded) ? LOADING : ITEM;
 }
 ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For our example, let&apos;s assume we want to display a list of movies.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
&lt;code&gt;List&amp;lt;Movies&amp;gt;&lt;/code&gt; (your data) must reside in the &lt;code&gt;RecyclerView.Adapter&lt;/code&gt; class only. You can access it via Getter Setters.&lt;/p&gt;
&lt;h5&gt;Adapter Helper Methods&lt;/h5&gt;
&lt;p&gt;Add the following methods to &lt;em&gt;PaginationAdapter&lt;/em&gt;. They will be useful for added data fetched via Pagination.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public void add(Movie mc) {
 movies.add(mc);
 notifyItemInserted(movies.size() - 1);
}

public void addAll(List &amp;lt; Movie &amp;gt; mcList) {
 for (Movie mc: mcList) {
  add(mc);
 }
}

public void remove(Movie city) {
 int position = movies.indexOf(city);
 if (position &amp;gt; -1) {
  movies.remove(position);
  notifyItemRemoved(position);
 }
}

public void clear() {
 isLoadingAdded = false;
 while (getItemCount() &amp;gt; 0) {
  remove(getItem(0));
 }
}

public boolean isEmpty() {
 return getItemCount() == 0;
}

public void addLoadingFooter() {
 isLoadingAdded = true;
 add(new Movie());
}

public void removeLoadingFooter() {
 isLoadingAdded = false;

 int position = movies.size() - 1;
 Movie item = getItem(position);
 if (item != null) {
  movies.remove(position);
  notifyItemRemoved(position);
 }
}

public Movie getItem(int position) {
 return movies.get(position);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is all for the adapter. Complete &lt;em&gt;PaginationAdapter&lt;/em&gt; code is available &lt;a href=&quot;https://github.com/Suleiman19/Android-Pagination-with-RecyclerView/blob/a1dd15095bdfc48fd41171061d1226963e07c0f8/app/src/main/java/com/suleiman/pagination/PaginationAdapter.java&quot;&gt;here&lt;/a&gt;, just in case.&lt;/p&gt;
&lt;h6&gt;Preparing RecyclerView&lt;/h6&gt;
&lt;pre&gt;&lt;code&gt;// Setup Layout Manager
linearLayoutManager = new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());

// Setup Adapter
PaginationAdapter adapter = new PaginationAdapter(this);
recyclerView.setAdapter(adapter);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Upon careful inspection, Pagination works in this flow:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Display loading progress (&lt;code&gt;ProgressDialog&lt;/code&gt;) on the empty screen while fetching initial data&lt;/li&gt;
&lt;li&gt;Hide &lt;code&gt;ProgressDialog&lt;/code&gt; and display data&lt;/li&gt;
&lt;li&gt;Detect user scroll to the end of the list&lt;/li&gt;
&lt;li&gt;Show &lt;code&gt;ProgressDialog&lt;/code&gt; at footer while fetching next page data&lt;/li&gt;
&lt;li&gt;Remove footer &lt;code&gt;ProgressDialog&lt;/code&gt; and display fetched data&lt;/li&gt;
&lt;li&gt;Repeat Steps 3, 4 &amp;amp; 5 until all pages have loaded&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Notice that the setup for certain steps is already in place. Loading initial data (page 0) will handle Step 1 and 2. &lt;em&gt;PaginationListener&lt;/em&gt; will handle Step 3 and 6. &lt;em&gt;PaginationAdapter&lt;/em&gt; helper methods will handle Step 4 and 5.&lt;/p&gt;
&lt;p&gt;The following code setup will show you how all this will tie together.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Activity Setup&lt;/h3&gt;
&lt;p&gt;Here&apos;s the entire &lt;em&gt;MainActivity.java&lt;/em&gt;. It should give you a clear understanding of how everything ties together.&lt;/p&gt;
&lt;p&gt;Be sure to note the variables here. As each plays a key part in the Pagination logic. Also, remember that &lt;code&gt;TOTAL_PAGES&lt;/code&gt; will be determined by how many pages your API has. Usually, this will be included in the paginated response.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; public class MainActivity extends AppCompatActivity {

 PaginationAdapter adapter;
 LinearLayoutManager linearLayoutManager;
 RecyclerView rv;
 ProgressBar progressBar;

 // Index from which pagination should start (0 is 1st page in our case)
 private static final int PAGE_START = 0;

 // Indicates if footer ProgressBar is shown (i.e. next page is loading)
 private boolean isLoading = false;

 // If current page is the last page (Pagination will stop after this page load)
 private boolean isLastPage = false;

 // total no. of pages to load. Initial load is page 0, after which 2 more pages will load.
 private int TOTAL_PAGES = 3;

 // indicates the current page which Pagination is fetching.
 private int currentPage = PAGE_START;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);
   ...

   // init views

   adapter = new PaginationAdapter(this);

   linearLayoutManager = new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
   rv.setLayoutManager(linearLayoutManager);
   rv.setAdapter(adapter);

   rv.addOnScrollListener(new PaginationScrollListener(linearLayoutManager) {
    @Override
    protected void loadMoreItems() {
     isLoading = true;
     //Increment page index to load the next one
     currentPage += 1;
     loadNextPage();
    }

    @Override
    public int getTotalPageCount() {
     return TOTAL_PAGES;
    }

    @Override
    public boolean isLastPage() {
     return isLastPage;
    }

    @Override
    public boolean isLoading() {
     return isLoading;
    }
   });
   loadFirstPage();
  }
  ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Loading Initial Data&lt;/h4&gt;
&lt;p&gt;Here’s how we’ll be using that method to perform the initial load (i.e. 1st-page request):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private void loadFirstPage() {
 // fetching dummy data
 List &amp;lt; Movie &amp;gt; movies = Movie.createMovies(adapter.getItemCount());
 progressBar.setVisibility(View.GONE);
 adapter.addAll(movies);

 if (currentPage &amp;lt;= TOTAL_PAGES) adapter.addLoadingFooter();
 else isLastPage = true;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can even mimic network delay, using a &lt;strong&gt;&lt;em&gt;&lt;a href=&quot;https://developer.android.com/reference/android/os/Handler&quot;&gt;Handler&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// mocking 1 second network delay
new Handler().postDelayed(new Runnable() {
 @Override
 public void run() {
  loadFirstPage();
 }
}, 1000);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once we load the initial request and get data, hide the &lt;code&gt;ProgressBar&lt;/code&gt;. Next, the fetched data is added to the adapter and notified. The &lt;code&gt;addAll()&lt;/code&gt; helper method in &lt;em&gt;PaginationAdapter&lt;/em&gt; accomplishes this.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
The initial data to be loaded is the 1st page (0th index). This must be a separate call, as the remaining pages are handled differently.&lt;/p&gt;
&lt;h4&gt;Using PaginationScrollListener&lt;/h4&gt;
&lt;p&gt;Notice how &lt;em&gt;PaginationScrollListener&lt;/em&gt; uses our &lt;code&gt;Activity&lt;/code&gt; defined flags. It needs the &lt;a href=&quot;https://developer.android.com/reference/android/support/v7/widget/RecyclerView.LayoutManager.html&quot;&gt;LayoutManager&lt;/a&gt; supplied to &lt;code&gt;RecyclerView&lt;/code&gt; to count and compare the number of items it has. This is more accurate to know how many items are actually in layout, rather than counting the List. But for now, its constructor only supports &lt;code&gt;LinearLayoutManager&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Once initial data has loaded, its time to listen to scroll changes and trigger the next page.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private void loadNextPage() {
 List &amp;lt; Movie &amp;gt; movies = Movie.createMovies(adapter.getItemCount()); // 1
 adapter.removeLoadingFooter(); // 2
 isLoading = false; // 3
 adapter.addAll(movies); // 4
 if (currentPage != TOTAL_PAGES) adapter.addLoadingFooter(); // 5
 else isLastPage = true;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now let&apos;s look at the steps we take to load page 2. This remains the same for all pages beyond this.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Get data (response) from API&lt;/li&gt;
&lt;li&gt;Remove footer &lt;code&gt;ProgressBar&lt;/code&gt; to make way for new data&lt;/li&gt;
&lt;li&gt;Indicate that the next page is currently not loading (using &lt;code&gt;isLoading&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Add your new data to the adapter&lt;/li&gt;
&lt;li&gt;Check if this is the last page. If not, add back the footer &lt;code&gt;ProgressBar&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;Final Output&lt;/h2&gt;
&lt;p&gt;As per our code setup, we create 10 dummy content per page load. The number of times Pagination will happen is 3 (&lt;code&gt;TOTAL_PAGE&lt;/code&gt;). Add that with the initial page load, and you&apos;re looking at 40 items in total.&lt;/p&gt;
&lt;p&gt;Go ahead and run the app.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/android-pagination-tutorial-getting-started-recyclerview/pagination-scroll-output.gif&quot; alt=&quot;Pagination result GIF&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Pagination result GIF&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Suleiman19/Android-Pagination-with-RecyclerView/tree/a1dd15095bdfc48fd41171061d1226963e07c0f8&quot;&gt;Download &lt;strong&gt;Source Code&lt;/strong&gt; from GitHub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;For Scroll listener, refer to this&lt;/em&gt; &lt;a href=&quot;https://github.com/Suleiman19/Android-Pagination-with-RecyclerView/blob/master/app/src/main/java/com/suleiman/pagination/utils/PaginationScrollListener.java&quot;&gt;&lt;em&gt;updated class - PaginationScrollListener&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Great job there! We now have a working Android app with a &lt;code&gt;RecyclerView&lt;/code&gt; that supports Pagination.&lt;/p&gt;
&lt;h3&gt;What&apos;s next?&lt;/h3&gt;
&lt;p&gt;In this article, we learned the logic behind paginating our data. However, this is just some dummy data. In the real world, we get data from an API. So with network calls in play, how would you paginate?&lt;/p&gt;
&lt;p&gt;You can read about this in Part 2 - &lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-recyclerview-tutorial-api-retrofit-gson/&quot;&gt;Pagination with real data via APIs using Retrofit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So how are you going to Paginate your apps? Do you think this approach is good? Or do you have something better in mind? Drop &apos;em in the comments below.&lt;/p&gt;
</content:encoded></item><item><title>Material Design Onboarding in Android- Quickstart (Tap Target)</title><link>https://blog.iamsuleiman.com/material-design-onboarding-android-quickstart-tap-target/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/material-design-onboarding-android-quickstart-tap-target/</guid><description>There are 3 Material Design Onboarding models in Android. In this tutorial, we&apos;ll learn about using the Quickstart model using TapTarget library. This</description><pubDate>Mon, 29 Aug 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;There are 3 Material Design Onboarding models in Android. In this tutorial, we&apos;ll learn about using the Quickstart model using TapTarget library. This is part of the &lt;a href=&quot;https://material.google.com/growth-communications/onboarding.html&quot;&gt;updated Material Design guidelines&lt;/a&gt; for apps. There are 3 types of Material Design onboarding models:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Self-Select&lt;/strong&gt;  Display a series of choices allowing users to customize their app experience&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Quickstart&lt;/strong&gt; Let users start using your app immediately and highlight actions they can take.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Top User Benefits&lt;/strong&gt; Display the top 3 features of your app with a carousel.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;./material-design-onboarding-android-quickstart-tap-target/material-design-onboarding-models-android.png&quot; alt=&quot;material design onboarding models android&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Self-Select, Quickstart, &amp;amp; Top User Benefits (Left to Right) - &lt;a href=&quot;http://material.google.com&quot;&gt;material.google.com&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Which Material Design Onboarding model to use?&lt;/h2&gt;
&lt;p&gt;The ‘&lt;strong&gt;Quickstart&lt;/strong&gt;&apos; model only serves you best when your app is something people are already familiar with. Like a chat, email, or camera app.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Provide value and encourage return visits by introducing users to new features and functionality at contextually relevant moments. - &lt;a href=&quot;https://material.google.com/growth-communications/feature-discovery.html#&quot;&gt;Feature Discovery (material.google.com)&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;However, if your app is something groundbreaking and new. If it has new features people don’t know how to use or aren’t familiar with. Then the ‘&lt;strong&gt;Top User Benefits&lt;/strong&gt;’ model is the best choice. If you’re app’s home feed is built based on user choices. Like how most social networks build your newsfeed the first time you join. Then for cases like these,  you have the ‘&lt;strong&gt;Self-Select&lt;/strong&gt;’ model. The table below can help decide which model best fits your Material Design app:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./material-design-onboarding-android-quickstart-tap-target/material-design-onboarding-models.png&quot; alt=&quot;material design onboarding models&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Source: &lt;a href=&quot;https://material.google.com/growth-communications/onboarding.html#onboarding-onboarding-models&quot;&gt;material.google.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; While onboarding is a crucial part of your app’s experience, your major focus must be on the app itself. As there is no use having an amazing onboarding experience, with a mediocre app. This increases user expectation, only to disappoint them later.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Quickstart Onboarding with Tap Target&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/material-design-onboarding-android-quickstart-tap-target/quickstart-tap-target-animation.gif&quot; alt=&quot;quickstart tap target animation&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Get the demo App &lt;a href=&quot;https://play.google.com/store/apps/details?id=uk.co.samuelwall.materialtaptargetprompt.sample&amp;amp;utm_source=global_co&amp;amp;utm_medium=prtnr&amp;amp;utm_content=Mar2515&amp;amp;utm_campaign=PartBadge&amp;amp;pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A feature discovery prompt focuses user attention on a specific UI element. - Tap target&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now that you know what the Tap Target effect looks like, let’s get to using it. Luckily, there’s a handy library called &lt;a href=&quot;https://github.com/sjwall/MaterialTapTargetPrompt&quot;&gt;Material TapTarget Prompt&lt;/a&gt; by Samuel Wall. So let’s use it to make quick work of this. Let’s start by adding the dependency. First, add the jcenter repository in your project level &lt;em&gt;build.gradle&lt;/em&gt; file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;repositories {
   jcenter()
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, add the library dependency to your app level &lt;em&gt;build.gradle&lt;/em&gt; file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dependencies { 
    compile &apos;uk.co.samuelwall:material-tap-target-prompt:1.1.4&apos; 
    ... 
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, decide upon which View must show the Tap Target.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;new MaterialTapTargetPrompt.Builder(YourActivity.this)
        .setTarget(findViewById(R.id.yourView))
        .setPrimaryText(&quot;Here is an interesting feature&quot;)
        .setSecondaryText(&quot;Tap here and you will be surprised&quot;)
        .setOnHidePromptListener(new MaterialTapTargetPrompt.OnHidePromptListener()
        {
            @Override
            public void onHidePrompt(MotionEvent event, boolean tappedTarget)
            {
                //TODO: Store in SharedPrefs so you don&apos;t show this prompt again.
            }

            @Override
            public void onHidePromptComplete()
            {
            }
        })
        .show();
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Use Tap Target sparingly&lt;/h3&gt;
&lt;p&gt;Use Tap Target to only highlight the most important features. It helps direct users to an action you want them to take. For example, take the Gmail Android app. Its primary action is to compose new email, which is prioritized with a Floating Action Button. Hence the FAB here, is a perfect case for Tap Target. &lt;strong&gt;READ ALSO:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/create-gmail-style-list-in-android/&quot;&gt;Create Gmail Style List in Android&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/implement-floating-action-button-part-1/&quot;&gt;Implement Floating Action Button – Part 1&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Keep in mind that &apos;Quickstart&apos; must only be used ONCE per feature. Introduce features to users one by one, gradually over time. This will involve you storing a &lt;code&gt;SharedPreference&lt;/code&gt;, once Tap Target has been displayed for a feature. You can always allow users to reset this via your app&apos;s Settings screen.&lt;/p&gt;
&lt;h3&gt;Customization&lt;/h3&gt;
&lt;p&gt;Here are a few Builder methods for the &lt;code&gt;MaterialTapTargetPrompt&lt;/code&gt; class:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Animation Interpolators-&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;setAnimationInterpolator(new FastOutSlowInInterpolator())
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Change highlighted icon (useful for color inversion when showing TapTarget)-&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;setIcon(R.drawable.ic_your_icon)
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Theming- Some properties you can define for styling TapTarget in &lt;em&gt;values/styles.xml&lt;/em&gt;-     &lt;em&gt;- focalRadius&lt;/em&gt;     &lt;em&gt;- backgroundColour&lt;/em&gt;     &lt;em&gt;- focalColour&lt;/em&gt;     &lt;em&gt;- primaryText&lt;/em&gt;     &lt;em&gt;- secondaryText&lt;/em&gt;     &lt;em&gt;- focalRadius&lt;/em&gt;     &lt;em&gt;- primaryTextSize&lt;/em&gt;     &lt;em&gt;- secondaryTextSize&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Remember that Quickstart will highlight a feature only ONCE. Also, it reveals each feature gradually over time as a user uses the app. The time span could be a week or so. Once a feature is highlighted, Tap Target is not displayed for it again. &lt;strong&gt;SAMPLE APP:&lt;/strong&gt; Available on &lt;a href=&quot;https://github.com/sjwall/MaterialTapTargetPrompt/tree/master/sample&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;We are already familiar with the &apos;&lt;strong&gt;Top User Benefits&lt;/strong&gt;’ model. Its the App intro sliders made with ViewPager. &lt;strong&gt;READ:&lt;/strong&gt; &lt;a href=&quot;https://blog.iamsuleiman.com/onboarding-android-viewpager-google-way/&quot;&gt;Onboarding with Android ViewPager: The Google Way&lt;/a&gt; The Quickstart model for Material Design onboarding is the fastest way to get users familiarize with your app. It uses Tap Target helps encourage user action. Quickstart takes users straight into your app. Then, on the way it sprinkles little tips and suggestions with how and what to use. This model in my opinion, is the best by far. Because mobile users do NOT like to wait! So which Material Design Onboarding model are you using in your Android app? Let me know in the comments, or subscribe below for more updates!&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;Header image: &lt;a href=&quot;https://material.uplabs.com/posts/onboarding-screens-e1501bc0-da3c-468f-a082-e4ec93675286&quot;&gt;Onboarding screens&lt;/a&gt; by Murat Gürsoy&lt;/em&gt;&lt;/p&gt;
</content:encoded></item><item><title>DayNight Theme Android Tutorial with Example</title><link>https://blog.iamsuleiman.com/daynight-theme-android-tutorial-example/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/daynight-theme-android-tutorial-example/</guid><description>The DayNight Theme was added to AppCompat with the realease of Support Library v23.2.0(http://android-developers.blogspot.in/2016/02/android-support-l</description><pubDate>Mon, 08 Aug 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The DayNight Theme was added to AppCompat with the &lt;a href=&quot;http://android-developers.blogspot.in/2016/02/android-support-library-232.html&quot;&gt;realease of Support Library v23.2.0&lt;/a&gt;. We can reference the theme using &lt;strong&gt;Theme.AppCompat.DayNight.&lt;/strong&gt; DayNight theme allows to switch between light(day) and dark(night) themes, based on the time. Keep in mind that it supports &lt;strong&gt;API 14+&lt;/strong&gt;. Any lower and it defaults to the Light theme. If you remember, this is just one of the goodies released by this support library version. Another great addition was Bottom Sheets, which you can read about &lt;a href=&quot;https://blog.iamsuleiman.com/bottom-sheet-android-design-support-library/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;The Old Days&lt;/h2&gt;
&lt;p&gt;Supporting both Light and Dark themes is pretty popular. It is desirable for any app that focuses on reading. Doing so requires maintaining two independent themes that inherit from:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Theme.AppCompat.Light&lt;/li&gt;
&lt;li&gt;Theme.AppCompat&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then, you would set the correct Theme in every Activity’s &lt;code&gt;onCreate()&lt;/code&gt;, before &lt;code&gt;super()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/daynight-theme-android-tutorial-example/android-night-mode-theme-change.gif&quot; alt=&quot;android night mode theme change&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Night mode as seen on &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.grafixartist.newslet&amp;amp;hl=en&quot;&gt;Newslet&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;app&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;setTheme(isDarkTheme? R.style.MyDarkTheme : R.style.MyLightTheme);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;isDarkTheme&lt;/code&gt; is a boolean to check if Dark Theme must be enabled. Ideally, you want users to set this via Settings (&lt;code&gt;SharedPreferences&lt;/code&gt;). This is how apps would handle theme switching before, but let’s look at a better alternative.&lt;/p&gt;
&lt;h2&gt;Using the DayNight Theme&lt;/h2&gt;
&lt;p&gt;Start by changing your parent theme in &lt;strong&gt;values/styles.xml&lt;/strong&gt;. You can inherit from any of the following themes:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./daynight-theme-android-tutorial-example/AppCompat-DayNight-choices--420x158.png&quot; alt=&quot;AppCompat DayNight choices&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&amp;lt;!--Your theme declarations--&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, you  have to tell our app to take advantage of this. Those familiar with switching themes before DayNight, will feel right at home. We set the theme, immediately in the Activity’s &lt;code&gt;onCreate()&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override
protected void onCreate(Bundle savedInstanceState) {

    AppCompatDelegate.setDefaultNightMode(
            AppCompatDelegate.MODE_NIGHT_AUTO);

    super.onCreate(savedInstanceState);
...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This little method tells your &lt;code&gt;Activity&lt;/code&gt; to use the DayNight theme. Notice that we do not use &lt;code&gt;setTheme()&lt;/code&gt; anymore. &lt;code&gt;AppCompatDelegate&lt;/code&gt; takes care of this.&lt;/p&gt;
&lt;h3&gt;Wait. What’s AppCompatDelegate?&lt;/h3&gt;
&lt;p&gt;In short, &lt;code&gt;AppCompatDelegate&lt;/code&gt; helps bring Material Design goodness to pre Lollipop Android versions.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It represents a delegate which you can use to extend AppCompat&apos;s support to any Activity. - &lt;a href=&quot;https://developer.android.com/reference/android/support/v7/app/AppCompatDelegate.html&quot;&gt;developer.android.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The AppCompat support libraries make this possible. That is why our Activities must extend from &lt;code&gt;AppCompatActivity&lt;/code&gt; and NOT from &lt;code&gt;Activity&lt;/code&gt;. &lt;a href=&quot;https://medium.com/google-developer-experts/how-to-add-toolbar-to-an-activity-which-doesn-t-extend-appcompatactivity-a07c026717b3#.mrrh546xc&quot;&gt;This medium post&lt;/a&gt; tells you how to use AppCompat goodness when not extending from &lt;code&gt;AppCompatActivity&lt;/code&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Let’s get back to the DayNight theme. You would have noticed one more thing in this method call.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;AppCompatDelegate.setDefaultNightMode(
 AppCompatDelegate.MODE_NIGHT_AUTO);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s right, you may wonder what &lt;strong&gt;MODE_NIGHT_AUTO&lt;/strong&gt; is. The curious one would’ve immediately done a &lt;em&gt;Cmd/Ctrl + Click&lt;/em&gt; to read its source. Let me highlight all available modes, so we can be clear what each one’s for.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;MODE_NIGHT_AUTO&lt;/strong&gt; - The app switches to night theme based on the time. It makes use of location APIs (if necessary permissions granted) for accuracy. Otherwise falls back to using system time.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MODE_NIGHT_FOLLOW_SYSTEM&lt;/strong&gt; - This is more of an app-wide setting for night mode. Uses the system Night Mode setting to determine if it is night or not.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MODE_NIGHT_NO&lt;/strong&gt; - Tells the app to never use night mode, regardless of time / location.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MODE_NIGHT_YES&lt;/strong&gt; -  Tells app to use night mode always, regardless of time / location.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;MODE_NIGHT_YES&lt;/strong&gt; can be used to test Night Theme. This is useful when its not actually night yet. You won&apos;t have to wait the whole day to test it!&lt;/p&gt;
&lt;h2&gt;Taking Control of DayNight theme&lt;/h2&gt;
&lt;p&gt;Now that you know how to use the DayNight theme, its time to customize it. Android allows us to override resources specific to Day or Night themes. You can do this using the -&lt;strong&gt;night&lt;/strong&gt; resource qualifier, appended to our resource folder names. For instance, I want to change my colors for the night theme. I can do so by creating a new resource, specific for that: &lt;strong&gt;res/values-night/colors.xml&lt;/strong&gt;. Then I can simply override the colors for them here. But for the sake of depth, let’s see how we can override the Night Theme itself. Create &lt;strong&gt;res/values-night/styles.xml&lt;/strong&gt;. Here we will override the Night Theme.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
 &amp;lt;item name=&quot;colorPrimary&quot;&amp;gt;@color/colorPrimaryNight&amp;lt;/item&amp;gt;
 &amp;lt;item name=&quot;colorPrimaryDark&quot;&amp;gt;@color/colorPrimaryDarkNight&amp;lt;/item&amp;gt;
 &amp;lt;item name=&quot;colorAccent&quot;&amp;gt;@color/colorAccentNight&amp;lt;/item&amp;gt;
 &amp;lt;item name=&quot;android:windowBackground&quot;&amp;gt;@color/bg_dark&amp;lt;/item&amp;gt;
 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this setup, we’re overriding Night Theme and specifying a new color scheme for it. You can even specify Night Theme specific drawables.&lt;/p&gt;
&lt;h3&gt;Setting DayNight for a single &lt;code&gt;Activity&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;You can also apply &lt;code&gt;Activity&lt;/code&gt; specific theme using this code snippet.  Use it prior to calling &lt;code&gt;super()&lt;/code&gt; in &lt;code&gt;onCreate()&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;getDelegate().setLocalNightMode(mode);
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Setting DayNight theme for entire app&lt;/h4&gt;
&lt;p&gt;Set this in your &lt;code&gt;Application&lt;/code&gt; class &lt;code&gt;onCreate()&lt;/code&gt;. This applies app-wide DayNight theme, depending on mode.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;AppCompatDelegate.setDefaultNightMode(mode);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; When referencing resources, always use from AppCompat (your theme). This ensures the correct theme attributes are applied. This ensures the DayNight theme is applied correctly and avoid weird UI issues. Such as black text against a dark background in Night mode. ;)&lt;/p&gt;
&lt;h2&gt;Result&lt;/h2&gt;
&lt;p&gt;I&apos;ve applied the DayNight Theme to an existing app. Let&apos;s see how it looks.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./daynight-theme-android-tutorial-example/android-daynight-theme_day.png&quot; alt=&quot;android daynight theme_day&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./daynight-theme-android-tutorial-example/android-daynight-theme-night.png&quot; alt=&quot;android daynight theme night&quot; /&gt;&lt;/p&gt;
&lt;p&gt;You&apos;ll notice that I&apos;ve completely changed the Material Design color palette for Night Theme. This is purely for demonstration purposes. Always remember to completely test both themes across both post and pre Lollipop Android versions. Despite our best attempts to maintain seamless UI, there always might be some issues. No harm in testing :) &lt;strong&gt;ALSO READ:&lt;/strong&gt; &lt;a href=&quot;https://blog.iamsuleiman.com/bottom-navigation-bar-android-tutorial/&quot;&gt;Bottom Navigation Bar Android Tutorial&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Things to keep in mind&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Do not use &lt;strong&gt;MODE_NIGHT_FOLLOW_SYSTEM&lt;/strong&gt; by default. As this is system dependent, set to false initially&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MODE_NIGHT_FOLLOW_SYSTEM&lt;/strong&gt; can be changed using &lt;code&gt;setLocalNightMode(int)&lt;/code&gt;. Allow the user to control this via settings, via Preferences&lt;/li&gt;
&lt;li&gt;Calling &lt;code&gt;AppCompatDelegate.setDefaultNightMode(mode)&lt;/code&gt; must be done BEFORE calling &lt;code&gt;super()&lt;/code&gt; in Activity &lt;code&gt;onCreate()&lt;/code&gt;. Otherwise you must &lt;code&gt;recreate()&lt;/code&gt; the Activity for the set theme to take effect&lt;/li&gt;
&lt;li&gt;Always reference resources and styles from the inherited theme. For example, you must reference primary color in styles as &lt;strong&gt;?attr/colorPrimary&lt;/strong&gt; and NOT &lt;strong&gt;@color/colorPrimary&lt;/strong&gt;. This ensures correct themed resources are used. It applies to all theme resources. It also eliminates UI inconsistencies, such as non-readable text.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;SOURCE CODE:&lt;/strong&gt; &lt;a href=&quot;https://github.com/Suleiman19/Bottom-Navigation-Demo/blob/master/app/src/main/res/values/styles.xml&quot;&gt;GitHub&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Quick Recap&lt;/h2&gt;
&lt;p&gt;Let&apos;s quickly review what we did.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Make our parent theme extend from any one of &lt;strong&gt;Theme.AppCompat.DayNight&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Tell our Activity(s) to set DayNight theme depending on the &lt;strong&gt;MODE_NIGHT&lt;/strong&gt; flags&lt;/li&gt;
&lt;li&gt;Override night specific theme resources using &lt;strong&gt;-night&lt;/strong&gt; qualifier for folders.&lt;/li&gt;
&lt;li&gt;Make sure to reference theme related attributes via styles.&lt;/li&gt;
&lt;li&gt;Remember to call &lt;code&gt;recreate()&lt;/code&gt; if theme is changed after &lt;code&gt;Activity&lt;/code&gt; creation.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;p&gt;Many apps allow switching between Light and Dark themes. But with no official support from Android, we maintained two separate themes. With DayNight theme, we can inherit from one base style that covers both themes. We can even override night theme and specify different resources. However, using two different themes is a matter of choice for users. Some like to use the Dark Theme when possible. So its a good idea to provide an option for the same. How do you adapt your UI&apos;s to the DayNight theme? Drop &apos;em in the comments below. Also don&apos;t forget to subscribe for latest posts and tips.&lt;/p&gt;
</content:encoded></item><item><title>Implement Parcelable to Bundle your POJOs</title><link>https://blog.iamsuleiman.com/implement-parcelable-bundle-pojos/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/implement-parcelable-bundle-pojos/</guid><description>Every Android Developer is familiar with passing data via a Bundle or Intent. In doing so, you would have wanted to pass your entire POJO (Plain Old J</description><pubDate>Sun, 26 Jun 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Every Android Developer is familiar with passing data via a  &lt;code&gt;Bundle&lt;/code&gt; or &lt;code&gt;Intent&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In doing so, you would have wanted to pass your entire &lt;strong&gt;POJO (Plain Old Java Object)&lt;/strong&gt; class,or &lt;code&gt;List&amp;lt;Bean&amp;gt;&lt;/code&gt;. But Intent or Bundle don&apos;t allow that right off the bat. The key lies in your Beans implementing &lt;a href=&quot;https://developer.android.com/reference/android/os/Parcelable.html&quot;&gt;Parcelable&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class YourModel implements Parcelable {

    // properties
    String name, url;

    public YourModel() { }

     // Getter Setters here

    // Parcelable methods
    protected YourModel(Parcel in) {
        name = in.readString();
        url = in.readString();
        // other properties
    }

    public static final Creator CREATOR = new Creator() {
        @Override
        public YourModel createFromParcel(Parcel in) {
            return new YourModel(in);
        }

        @Override
        public YourModel[] newArray(int size) {
            return new YourModel[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeString(url);
        // other properties
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After that, you simply pass your model class data like this:&lt;/p&gt;
&lt;h2&gt;Passing via Intent&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;intent.putParcelableArrayListExtra(&quot;listofmodels&quot;, (ArrayList) yourModels);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;List of YourModel&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;intent.putExtra(&quot;singlemodel&quot;, (Parcelable) yourModel);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Single YourModel object&lt;/p&gt;
&lt;h3&gt;Passing YourModel via a Bundle&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;bundle.putParcelableArrayList(&quot;listofmodels&quot;, (ArrayList) yourModels);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;List of YourModel&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bundle.putParcelable(&quot;singlemodel&quot;, yourModel);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Single YourModel object&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PRO-TIP:&lt;/strong&gt; You can alternatively implement &lt;a href=&quot;https://developer.android.com/reference/java/io/Serializable.html&quot;&gt;&lt;strong&gt;Serializable&lt;/strong&gt;&lt;/a&gt; to achieve a similar result!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;USEFUL RESOURCES:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/johncarl81/parceler&quot;&gt;Parceler&lt;/a&gt; library by John Ericksen&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/a/3323554&quot;&gt;Difference between Parcelable and Serializable&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>RecyclerView Adapter in Android, made Fast and Easy</title><link>https://blog.iamsuleiman.com/recyclerview-adapter-android-made-fast-easy/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/recyclerview-adapter-android-made-fast-easy/</guid><description>Every time we think of creating a RecyclerView, we dread the amount of code that must go into the adapter. Also, if that adapter has many ViewHolders,</description><pubDate>Tue, 07 Jun 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Every time we think of creating a &lt;code&gt;RecyclerView&lt;/code&gt;, we dread the amount of code that must go into the adapter. Also, if that adapter has many ViewHolders, then god save us! Also, I haven&apos;t even mentioned click listeners, drag and drop and other fancy stuff. If you&apos;ve freaked out already about the effort needed for all that, then this post is for you. Of course, we all are familiar with the &lt;code&gt;RecyclerView.Adapter&lt;/code&gt; boilerplate code. But writing the same code setup again and again is a waste of time. Surely there must be a better way?&lt;/p&gt;
&lt;h2&gt;Say hello to &lt;a href=&quot;https://github.com/mikepenz/FastAdapter&quot;&gt;FastAdapter&lt;/a&gt;!&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;The bullet proof, fast and easy to use adapter library, which minimizes developing time to a fraction... - Mike Penz&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;FastAdapter is made by &lt;a href=&quot;https://github.com/mikepenz&quot;&gt;Mike Penz&lt;/a&gt;. The developer of popular libraries such as MaterialDrawer and AboutLibraries. FastAdapter reduces your time spent on Adapter code. Moreover, it offers a lot of features so it wouldn&apos;t limit your app in any way. With tons of features offered, consider replacing your &apos;regular&apos; RecyclerView Adapters with FastAdapter. Click listeners, Multi-selection, filtering, drag and drop, headers and much more. You name it, you got it!&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Getting Started&lt;/h3&gt;
&lt;p&gt;Start using FastAdapter by adding the following dependencies:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;compile(&apos;com.mikepenz:fastadapter:1.5.2@aar&apos;) {
        transitive = true
    }
compile &apos;com.mikepenz:fastadapter-extensions:1.5.1@aar&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Creating the Model class&lt;/h4&gt;
&lt;p&gt;Let&apos;s say we&apos;re creating an app about the types of Mango (which happens to be my favourite fruit). So I name my model class simply, &lt;strong&gt;Mango&lt;/strong&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Mango {

    private String name, description, imageUrl;

    public Mango() { }

    public Mango(String name, String description, String imageUrl) {
        this.name = name;
        this.description = description;
        this.imageUrl = imageUrl;
    }

    // Your variable Getter Setters here
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Implementing the Adapter&lt;/h4&gt;
&lt;p&gt;FastAdapter makes use of your model class to create the &lt;code&gt;RecyclerView.Adapter&lt;/code&gt; and &lt;code&gt;RecyclerView.ViewHolder&lt;/code&gt;. Extend your model with &lt;code&gt;AbstractItem&amp;lt;Item, Item.ViewHolder&amp;gt;&lt;/code&gt; and implement its methods:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;getType()&lt;/code&gt; - return a unique ID (of your parent layout)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getLayoutRes()&lt;/code&gt; - return your XML layout resource&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bindView()&lt;/code&gt; - RecyclerView&apos;s &lt;code&gt;onBindViewHolder()&lt;/code&gt; method&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;public class Mango extends AbstractItem {

    private String name, imageUrl, description;

    public Mango() { }

    public Mango(String name, String imageUrl) {
        this.name = name;
        this.imageUrl = imageUrl;
    }

     // Your Getter Setters here
     
    // Fast Adapter methods
    @Override
    public int getType() { return R.id.item_card; }

    @Override
    public int getLayoutRes() { return R.layout.list_item; }

    @Override
    public void bindView(ViewHolder holder) {
        super.bindView(holder);
    }

    // Manually create the ViewHolder class
    protected static class ViewHolder extends RecyclerView.ViewHolder {
  
        //TODO: Declare your UI widgets here

        public ViewHolder(View itemView) {
            super(itemView);
            //TODO: init UI
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./recyclerview-adapter-android-made-fast-easy/recyclerview-fastadapter-mango-list.png&quot; alt=&quot;recyclerview fastadapter mango list&quot; title=&quot;Simple List using FastAdapter&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;Marrying FastAdapter to RecyclerView&lt;/h4&gt;
&lt;p&gt;With that in place, you can finally attach FastAdapter to your RecyclerView:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;recyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));

FastItemAdapter fastAdapter = new FastItemAdapter&amp;lt;&amp;gt;();
recyclerView.setAdapter(fastAdapter);

// Fetch your data here
List mangoes = loadMangoes();

fastAdapter.add(mangoes);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is all we need to do! If we run our app now, we&apos;d get a RecyclerView populated with a list of mangoes. So instead of reviewing what we just did. Let&apos;s what what we did NOT do for our adapter:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;create an exclusive class for &lt;code&gt;RecyclerView.Adapter&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;inflate an item layout&lt;/li&gt;
&lt;li&gt;bother with &lt;code&gt;getItemCount()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So I&apos;m sure you&apos;ll believe me now. FastAdapter did quick work of creating a list. But surely you want to do more than just display a list? Here is where FastAdapter shines.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Feature List&lt;/h3&gt;
&lt;p&gt;Let&apos;s see how some popular &lt;code&gt;RecyclerView&lt;/code&gt; features are done with FastAdapter. Use the below index to navigate.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#clicklistener&quot;&gt;Click listener&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#filterdata&quot;&gt;Filtering data with Search&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#dragdrop&quot;&gt;Drag and drop&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#multiselectcab&quot;&gt;Multi-select with CAB (Contextual Action Bar) and Undo action&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#headerview&quot;&gt;Adding Header view (multiple ViewHolders)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#infinitescrolling&quot;&gt;Infinite (endless) scrolling&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;1. Click Listener&lt;/h4&gt;
&lt;p&gt;Enable withSelectable for FastAdapter, and then set its click listener.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fastAdapter.withSelectable(true);

fastAdapter.withOnClickListener(new FastAdapter.OnClickListener() {
            @Override
            public boolean onClick(View v, IAdapter adapter, Mango item, int position) {
               // Handle click here
                return true;
            }
        });
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2. Filtering data with Search&lt;/h4&gt;
&lt;p&gt;If our app uses a &lt;a href=&quot;https://developer.android.com/reference/android/widget/SearchView.html&quot;&gt;&lt;code&gt;SearchView&lt;/code&gt;&lt;/a&gt;, and we want to filter our adapter data based on its results. FastAdapter has provision for that too.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Call this in your Search listener
fastAdapter.filter(&quot;yourSearchTerm&quot;);

fastAdapter.withFilterPredicate(new IItemAdapter.Predicate() {
            @Override
            public boolean filter(Mango item, CharSequence constraint) {
                return item.getName().startsWith(String.valueOf(constraint));
            }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the &lt;code&gt;filter(Mango item, CharSequence constraint)&lt;/code&gt; method. Return true means remove those items from the adapter, and retain those items which return false. If you&apos;re using SearchView, call &lt;code&gt;filter()&lt;/code&gt; in its  &lt;code&gt;onQueryTextSubmit(String s)&lt;/code&gt; and &lt;code&gt;onQueryTextChange(String s)&lt;/code&gt; methods.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/recyclerview-adapter-android-made-fast-easy/filteradapter.gif&quot; alt=&quot;filteradapter&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;3. Drag and Drop&lt;/h4&gt;
&lt;p&gt;Start by creating an instance of &lt;strong&gt;&lt;code&gt;SimpleDragCallback&lt;/code&gt;&lt;/strong&gt; (courtesy of FastAdapter). Next, use it to initialize an &lt;code&gt;ItemTouchHelper&lt;/code&gt;. Finally attach the ItemTouchHelper to RecyclerView.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SimpleDragCallback dragCallback = new SimpleDragCallback(this);
ItemTouchHelper touchHelper = new ItemTouchHelper(dragCallback);
touchHelper.attachToRecyclerView(recyclerView);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Implement the &lt;code&gt;ItemTouchCallback&lt;/code&gt; interface in your Activity. It implements the itemTouchOnMove() method. Add the following code to it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override
   public boolean itemTouchOnMove(int oldPosition, int newPosition) {
       Collections.swap(fastAdapter.getAdapterItems(), oldPosition, newPosition); // change position
       fastAdapter.notifyAdapterItemMoved(oldPosition, newPosition);
       return true;
   }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/recyclerview-adapter-android-made-fast-easy/dragdrop.gif&quot; alt=&quot;dragdrop&quot; title=&quot;FastAdapter with Drag and Drop support&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;4. Multi-Select with CAB (Contextual Action Bar) and Undo action&lt;/h4&gt;
&lt;p&gt;Start by creating an inner class &lt;strong&gt;ActionBarCallBack&lt;/strong&gt; for your Activity, and implement &lt;code&gt;ActionMode.Callback&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private class ActionBarCallBack implements ActionMode.Callback {
        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) { return true; }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            mode.finish();
            return true;
        }

        @Override
        public void onDestroyActionMode(ActionMode mode) { }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Initialize an ActionModeHelper (by FastAdapter).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fastAdapter.setHasStableIds(true);
fastAdapter.withSelectable(true);
fastAdapter.withMultiSelect(true);
fastAdapter.withSelectOnLongClick(true);

actionModeHelper = new ActionModeHelper(fastAdapter, R.menu.cab, new ActionBarCallBack());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Regular onClick methods are used for other actions, such as for detail navigation. Hence FastAdapter provides a &lt;strong&gt;preClick&lt;/strong&gt; and &lt;strong&gt;preLongClick&lt;/strong&gt; listener for handling CAB.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fastAdapter.withOnPreClickListener(new FastAdapter.OnClickListener() {
            @Override
            public boolean onClick(View v, IAdapter adapter, Mango item, int position) {
                Boolean res = actionModeHelper.onClick(item);
                return res != null ? res : false;
            }
});

fastAdapter.withOnPreLongClickListener(new FastAdapter.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v, IAdapter adapter, Mango item, int position) {
                ActionMode actionMode = actionModeHelper.onLongClick(MainActivity.this, position);
                if (actionMode != null) {
                    // Set CAB background color
                   findViewById(R.id.action_mode_bar).setBackgroundColor(Color.GRAY);
                }
                return actionMode != null;
            }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that we do not consume &lt;strong&gt;preClick&lt;/strong&gt; if Action Mode is not enabled. If that&apos;s the case, we return false. This allows us the regular &lt;strong&gt;onClick&lt;/strong&gt; method to be handled. If you&apos;re also using &lt;code&gt;withOnClickListener()&lt;/code&gt;, don&apos;t forget to return false. Lastly, enable &lt;code&gt;windowActionModeOverlay&lt;/code&gt; in your &lt;strong&gt;AppTheme&lt;/strong&gt;, found in &lt;em&gt;values/styles.xml&lt;/em&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/recyclerview-adapter-android-made-fast-easy/multiselect.gif&quot; alt=&quot;multiselect&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Multi-select and CAB (Contextual Action Bar)&lt;/p&gt;
&lt;h5&gt;Undo Action&lt;/h5&gt;
&lt;p&gt;Deleting multi-selection items in CAB mode, works in conjunction with &lt;code&gt;UndoHelper&lt;/code&gt;. This helper class will allow us to perform deletion on the multi-selected items.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;UndoHelper undoHelper = new UndoHelper(fastAdapter, new UndoHelper.UndoListener() {
            @Override
            public void commitRemove(Set positions, ArrayList&amp;gt; removed) {
                Log.d(&quot;remove&quot;, &quot;removed: &quot; + removed.size());
            }
        });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For this interface implementation, we log the removed items count. &lt;code&gt;UndoHelper.UndoListener&lt;/code&gt; is also useful to know the positions of the removed items. Remember the inner class &lt;strong&gt;ActionBarCallBack&lt;/strong&gt; that we created? Modify its &lt;code&gt;onActionItemClicked()&lt;/code&gt; method to this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
    undoHelper.remove(findViewById(android.R.id.content), &quot;Item removed&quot;, &quot;Undo&quot;, Snackbar.LENGTH_LONG, fastAdapter.getSelections());
    mode.finish();
    return true;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We have just called the UndoHelper&apos;s &lt;code&gt;remove()&lt;/code&gt; method. This essentially removes the multi-selected items. Upon removal, it displays a &lt;a href=&quot;https://developer.android.com/reference/android/support/design/widget/Snackbar.html&quot;&gt;SnackBar&lt;/a&gt; notifying us on success. It also gives us a prompt to undo the last removal, if we want to.&lt;/p&gt;
&lt;h4&gt;5. Adding Header View (multiple ViewHolders)&lt;/h4&gt;
&lt;p&gt;You could modify the existing Mango model for this. But for the sake of code cleanliness, let&apos;s maintain a new model class for our Header view.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Header extends AbstractItem {

    String title;

    public Header(String title) {
        this.title = title;
    }

     // Your getter setters here

    // AbstractItem methods
    @Override
    public int getType() {
        return R.id.header_text;
    }

    @Override
    public int getLayoutRes() {
        return R.layout.header_item;
    }

    @Override
    public void bindView(ViewHolder holder) {
        super.bindView(holder);

        holder.textView.setText(title);
    }

    protected static class ViewHolder extends RecyclerView.ViewHolder {
        @BindView(R.id.header_text) TextView textView;

        public ViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nothing fancy here. The &lt;strong&gt;Header&lt;/strong&gt; model supports displaying a simple &lt;code&gt;TextView&lt;/code&gt;. Start by initializing your Adapter variables:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FastItemAdapter fastAdapter = new FastItemAdapter&amp;lt;&amp;gt;();
fastAdapter.setHasStableIds(true);
fastAdapter.withSelectable(true);

HeaderAdapter
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you recall from earlier, we initialized our FastAdapter like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FastItemAdapter fastAdapter = new FastItemAdapter&amp;lt;&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that now, we don&apos;t explicitly mention the type. This allows our FastAdapter to hold data from both &lt;strong&gt;Mango&lt;/strong&gt; and &lt;strong&gt;Header&lt;/strong&gt; models. Alternatively, you can initialize a generic type FastAdapter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FastItemAdapter fastAdapter = new FastItemAdapter&amp;lt;&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;IItem&lt;/code&gt; is the base type for your Model classes. So if you initialize like this, remember to cast your models to &lt;code&gt;IItem&lt;/code&gt; when adding data.&lt;/p&gt;
&lt;h5&gt;Setting the adapter&lt;/h5&gt;
&lt;p&gt;This is slightly different from last time. We set both, &lt;code&gt;headerAdapter&lt;/code&gt; and &lt;code&gt;fastAdapter&lt;/code&gt; to our &lt;code&gt;RecyclerView&lt;/code&gt; using the &lt;code&gt;wrap(FastAdapter)&lt;/code&gt; method.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;recyclerView.setAdapter(headerAdapter.wrap(fastAdapter));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you wish to have a third, different type of ViewHolder, its possible with an additional wrap() method.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;recyclerView.setAdapter(thirdAdapter.wrap(headerAdapter.wrap(fastAdapter)));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Adding data&lt;/strong&gt; All data is added to FastAdapter. For this example, I want one Header view at the top, and another in the middle. In an ideal scenario, you will have different subsets of data with header titles for each of them. So for my case, I add my data like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; int half = mangoes.size() / 2;

fastAdapter.add(0, new Header(&quot;First half&quot;).withIdentifier(1));
fastAdapter.add(1, mangoes.subList(0, half));
fastAdapter.add(half + 1, new Header(&quot;Second half&quot;).withIdentifier(2));
fastAdapter.add(half + 2, mangoes.subList(0, half));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I already have my list of mangoes. So I add half of them under the first header, and the other half under the second. The above code snippet demonstrates that. Note the increments to the &lt;code&gt;half&lt;/code&gt; integer. The position is incremented like you would for any List.&lt;/p&gt;
&lt;h6&gt;Manipulating with different ViewHolders&lt;/h6&gt;
&lt;p&gt;Our FastAdapter now supports and holds data of different View types. So how do we manipulate stuff? Like handle clicks, and all the fancy stuff mentioned above? In short, the answer is to use &lt;strong&gt;&lt;a href=&quot;http://www.javatpoint.com/downcasting-with-instanceof-operator&quot;&gt;instanceof&lt;/a&gt;&lt;/strong&gt;. As an example, I&apos;ll show you how to modify FastAdapter&apos;s click listener:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fastAdapter.withOnClickListener(new FastAdapter.OnClickListener() {
            @Override
            public boolean onClick(View v, IAdapter adapter, IItem item, int position) {

                if (item instanceof Mango) {
                   // Do your thing!
                } else if (item instanceof Header) {
                   // Header clicks usually don&apos;t do anything. Ignore if you like.
                }
                return true;
            }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice the difference here? When we did the same click listener earlier, the &lt;code&gt;onClick()&lt;/code&gt; passed us a Mango item. But since FastAdapter now is generic, it passes us an &lt;code&gt;IItem&lt;/code&gt; (base class) object.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/recyclerview-adapter-android-made-fast-easy/header-view.gif&quot; alt=&quot;header-view&quot; title=&quot;FastAdapter with multiple ViewHolders&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;6.  Infinite (endless) scrolling&lt;/h4&gt;
&lt;p&gt;This feature is used by almost all social networking apps. They load N number of posts first. After you reach the end of it, they show a loading indicator and then load N more. This is known as &lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-tutorial-getting-started-recyclerview/&quot;&gt;endless scrolling or pagination&lt;/a&gt;. The key to doing this lies in RecyclerView&apos;s &lt;code&gt;addOnScrollListener()&lt;/code&gt; method. But we both know, inside the listener is where the real hardship is. For this, FastAdapter saves us with &lt;code&gt;EndlessRecyclerOnScrollListener()&lt;/code&gt;. First, let us create a &lt;code&gt;FooterAdapter&lt;/code&gt;. We need this to display a loading &lt;code&gt;ProgressBar&lt;/code&gt; at the end of our list.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FooterAdapter footerAdapter = new FooterAdapter&amp;lt;&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that &lt;strong&gt;ProgressItem&lt;/strong&gt; is provided by FastAdapter&apos;s extensions. It is not part of the core library. So let&apos;s safely use both core and extension libraries shall we? After all, they are very useful!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;recyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener() {
            @Override
            public void onLoadMore(int currentPage) {
                footerAdapter.clear();
                footerAdapter.add(new ProgressItem().withEnabled(false));

                // Load your items here and add it to FastAdapter
                fastAdapter.add(newMangoes);
            }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Really, that&apos;s all there is to do infinite scrolling. It&apos;s that easy! See the results for yourself.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/recyclerview-adapter-android-made-fast-easy/endless-scrolling.gif&quot; alt=&quot;endless-scrolling&quot; title=&quot;Pagination - Endless or infinite scrolling with FastAdapter&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Alternatively, if you want to implement Pagination with a regular &lt;code&gt;RecyclerView.Adapter&lt;/code&gt;, then read &lt;a href=&quot;https://blog.iamsuleiman.com/android-pagination-tutorial-getting-started-recyclerview/&quot;&gt;Android Pagination with RecyclerView&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Wrapping it up&lt;/h2&gt;
&lt;p&gt;Wow, I think this was the longest post ever! I applaud your patience and perseverance for getting to the end of this post. RecyclerView&apos;s magic resides in its Adapter. FastAdapter knows this and simplifies it. It is more than just a convenience library. If you do a lot of Adapter manipulations, then having FastAdapter in your arsenal is an absolute must! &lt;strong&gt;RESOURCES:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/mikepenz/FastAdapter&quot;&gt;mikepenz/FastAdapter library on GitHub&lt;/a&gt; (library and samples)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;SOURCE CODE:&lt;/strong&gt; Relevant code snippets of mine, for this post can be found on my GitHub Gist &lt;a href=&quot;https://gist.github.com/Suleiman19/833c4a6a83464e711f96ac653fead0fc&quot;&gt;here&lt;/a&gt;. FastAdapter let&apos;s you do almost anything you would with an ordinary &lt;code&gt;RecyclerView&lt;/code&gt;. Just, more easier and faster. I&apos;m going to start using FastAdapter for my existing and future projects. What about you? Let me know in the comments below!&lt;/p&gt;
</content:encoded></item><item><title>Prepare your apps for Multi-Window in Android N</title><link>https://blog.iamsuleiman.com/prepare-apps-multi-window-in-android-n/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/prepare-apps-multi-window-in-android-n/</guid><description>Android 7 Nougat introduced Multi-Window, a new feature that enables multi-tasking. In this post, let&apos;s make or Android apps Multi-Window compatible. </description><pubDate>Tue, 17 May 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Android 7 Nougat introduced Multi-Window, a new feature that enables multi-tasking. In this post, let&apos;s make or Android apps Multi-Window compatible. Android Nougat brings in a host of improvements and changes. Many of you already know &lt;a href=&quot;http://www.androidauthority.com/android-7-0-features-673002/&quot;&gt;what&apos;s new in Android N&lt;/a&gt;. So if we developers want to support the latest Android version, there&apos;s more work cut out for us.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./prepare-apps-multi-window-in-android-n/mw-splitscreen.png&quot; alt=&quot;Android N Multi-Window from developer.android.com&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Android N Multi-Window from &lt;a href=&quot;http://developer.android.com/preview/features/multi-window.html&quot;&gt;developer.android.com&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Why bother?&lt;/h2&gt;
&lt;p&gt;It might be alright to ignore supporting Multi-Window. But what Ian Lake said, should change your mind.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Keep in mind that &lt;strong&gt;multi-window is enabled by default&lt;/strong&gt; - even if you don&apos;t target Android N, your app will be available in multi-window mode*. Start thinking about it now! * With the exception of apps with a fixed orientation or the immersive flag set in the manifest. - &lt;a href=&quot;https://plus.google.com/+AndroidDevelopers/posts/eKMB2stK41N&quot;&gt;source&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I hope that convinced you that Multi-Window in Android N is important. Let&apos;s get started. We&apos;ll create a simple list detail app using RecyclerView. Then enable Multi-Window on one Activity. Finally see how we can handle it. For this tutorial, I&apos;m creating a list of the Avengers.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Creating an Android Nougat app&lt;/h2&gt;
&lt;p&gt;Android Nougat 7.1 has just released, so let&apos;s jump straight to using that. Make sure you&apos;ve downloaded the following via Android SDK Manager:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SDK Build Tools &amp;amp; Platform Tools (v 25)&lt;/li&gt;
&lt;li&gt;Android 7.1.1 (API 25)&lt;/li&gt;
&lt;li&gt;Latest Support Libraries&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&apos;s how my project&apos;s &lt;em&gt;app/&lt;strong&gt;build.gradle&lt;/strong&gt;&lt;/em&gt; looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;android {
    compileSdkVersion 25
    buildToolsVersion &quot;25.0.0&quot;

    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 25
        ...
    }
 ...
}

dependencies {
    compile &apos;com.android.support:appcompat-v7:25.0.0&apos;
    ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Enabling Multi-Window in Android N&lt;/h3&gt;
&lt;p&gt;Add a layout tag under your activity tag in &lt;strong&gt;AndroidManifest.xml&lt;/strong&gt;. Add in these layout attributes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;... 

            
            ...

...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are a few things to note here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;android:resizeableActivity=&quot;true&quot;&lt;/code&gt; tells Android that your app supports Multi-Window&lt;/li&gt;
&lt;li&gt;default Height &amp;amp; Width are the dimensions the app takes by default, when entering Multi-Window&lt;/li&gt;
&lt;li&gt;&lt;code&gt;minHeight&lt;/code&gt; and &lt;code&gt;minWidth&lt;/code&gt; are the smallest dimensions the app can be resized to&lt;/li&gt;
&lt;li&gt;&lt;code&gt;android:gravity&lt;/code&gt; dictates the initial position of the app in freeform mode&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;220dp&lt;/strong&gt; is the minimum dimensions for an app. So make your app layout compatible from that breakpoint onwards. &lt;strong&gt;NOTE:&lt;/strong&gt; While 220dp is the lowest size possible, you can set any minimum dimension in the Manifest file, as mentioned above.&lt;/p&gt;
&lt;h4&gt;Wait, now what&apos;s Freeform Mode?&lt;/h4&gt;
&lt;p&gt;In addition to Multi-Window in Android N, Tablets have Freeform mode. Similar to opening multiple windows on your desktop OS. Maybe a GIF will help you better understand.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/prepare-apps-multi-window-in-android-n/lrrvt2kogrct5bueobzm.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;GIF from &lt;a href=&quot;http://lifehacker.com/heres-what-freeform-windows-in-android-n-look-like-and-1766353465&quot;&gt;Lifehacker&lt;/a&gt; But let&apos;s just focus on Multi-Window for now. By adding &lt;code&gt;&amp;lt;layout /&amp;gt;&lt;/code&gt; inside &lt;code&gt;&amp;lt;activity /&amp;gt;&lt;/code&gt; in your Manifest, I could say we&apos;re pretty much done. That is all that&apos;s needed to enable Multi-Window.But I&apos;m sure you&apos;re not here for JUST that? Apart from resizing, the layout needs to adapt to size changes.&lt;/p&gt;
&lt;h3&gt;Making an adaptive UI&lt;/h3&gt;
&lt;p&gt;You must be wondering, &quot;What needs to be done, to make my UI adaptive?&quot;. Well there&apos;s nothing new you have to do. If you think hard enough, you&apos;ll realise the solution already resides within Android. Yes, its Android&apos;s &lt;strong&gt;resource directory&lt;/strong&gt;! Those familiar with designing adaptive UI for tablets will feel right at home. &lt;strong&gt;READ ALSO:&lt;/strong&gt; &lt;a href=&quot;https://blog.iamsuleiman.com/material-design-for-tablets/&quot;&gt;Material Design for Tablets&lt;/a&gt; If not, I strongly recommend you read the above post, for an up-to-date primer on designing adaptive Android layouts. So let&apos;s see an example first. Here I have a list of the original Marvel Avengers team.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./prepare-apps-multi-window-in-android-n/normal-view.png&quot; alt=&quot;normal view&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./prepare-apps-multi-window-in-android-n/multi-window.png&quot; alt=&quot;multi window&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Looking good on the left, but in Multi-Window mode? Not much. The cards are huge for such a tiny window. Let&apos;s make each card&apos;s height smaller, so we can view more in a smaller window. Also, did you notice? Android automatically resized the Toolbar&apos;s title in Multi-Window. &lt;strong&gt;TIP: How to launch Multi-Window in Android Nougat&lt;/strong&gt; Long-press the Recents button. Or from the Recents screen, long-press + drag a window onto the highlighted area. Create &lt;strong&gt;res&amp;gt;values-h500dp&lt;/strong&gt; folder. Those familiar with the &apos;smallest-width&apos; concept for creating layouts will immediately recognize that it works the same way for height. &lt;strong&gt;NOTE:&lt;/strong&gt; This ideally works on the smallest-width concept. However, smallest-height &lt;strong&gt;sh400dp&lt;/strong&gt; doesn&apos;t seem to work, and gives a compile error (weird)! However, if anyone can clarify this for me, it would be great! Create &lt;strong&gt;dimens.xml&lt;/strong&gt; under &lt;strong&gt;values-h500dp&lt;/strong&gt; folder. Doing so tells Android that &quot;Hey,  if my app&apos;s height is greater or equal to 500dp, use the &lt;strong&gt;values-h500dp&lt;/strong&gt; folder, otherwise go for the regular &lt;strong&gt;res/values&lt;/strong&gt; folder&quot;. I want my card&apos;s height to be smaller on Multi-Window. So here&apos;s how I define it&apos;s value:  &lt;em&gt;values-h500dp/dimens.xml&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;96dp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;values/dimens.xml&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;80dp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this way, if my app&apos;s height will be greater or equal to 500dp, card will be 96dp tall. If its lesser than 500dp in height, the card will be 80dp tall. Similarly, you can adapt your UI by providing alternate dimensions under the appropriate values folder. Here&apos;s the result of how the list adapts in Multi-Window:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./prepare-apps-multi-window-in-android-n/normal-view.png&quot; alt=&quot;normal view&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./prepare-apps-multi-window-in-android-n/multi-window-adapted.png&quot; alt=&quot;multi window-adapted&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Looking good on landscape too!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./prepare-apps-multi-window-in-android-n/multi-window-landscape.png&quot; alt=&quot;multi window landscape&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;Listening to Multi-Window changes&lt;/h4&gt;
&lt;p&gt;Use the method &lt;code&gt;isInMultiWindowMode()&lt;/code&gt; in your Activity, to determine if your app is in Multi-Window. Note that our Activity&apos;s lifecycle is not altered. When you alternate between the 2 apps in Multi-Window, your app pauses and resumes accordingly. &lt;strong&gt;SOURCE CODE:&lt;/strong&gt; Available on &lt;a href=&quot;https://github.com/Suleiman19/Android-N-Sample&quot;&gt;GitHub&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Things to remember&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Make sure you&apos;re handling configuration changes properly using &lt;code&gt;onSavedInstanceState()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Don&apos;t entirely change the UI, so users can avoid relearning the interface&lt;/li&gt;
&lt;li&gt;Handle both portrait and landscape changes&lt;/li&gt;
&lt;li&gt;Make the UI adapt from a minimum size of &lt;strong&gt;220dp&lt;/strong&gt; and up&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Multi-Window in Android N highly encourages multi-tasking. Expect to see a lot of apps use this feature. Are you adapting your apps to Multi-Window? How have you modified your layouts? Drop &apos;em in the comments or subscribe below for future posts!&lt;/p&gt;
</content:encoded></item><item><title>People API Android Tutorial - Part 1</title><link>https://blog.iamsuleiman.com/people-api-android-tutorial-1/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/people-api-android-tutorial-1/</guid><description>Imagine having access to your contacts including data about them and their connections, via a single API? Combine the Contacts API and Google+ API and</description><pubDate>Tue, 19 Apr 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Imagine having access to your contacts including data about them and their connections, via a single API? Combine the Contacts API and Google+ API and we have the People API. You can read the announcement on &lt;a href=&quot;https://developers.googleblog.com/2016/02/announcing-people-api.html&quot;&gt;Google Developers Blog&lt;/a&gt;. Never was a fan of the Contacts API in Android, so I&apos;m glad this came into picture. In this two-part post, we&apos;ll look at using the People API.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The People API lets you list authenticated users&apos; &lt;a href=&quot;https://www.google.com/contacts&quot;&gt;Contacts&lt;/a&gt; and retrieve profile information for authenticated users and their contacts.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Part 1 of this post covers how to create a project via Google API Console. Then we&apos;ll see how to configure it, enable the People API and make it ready for access via our Android app. If you feel you&apos;re already familiar with all this, jump ahead to &lt;a href=&quot;https://blog.iamsuleiman.com/people-api-android-tutorial-2/&quot;&gt;part 2&lt;/a&gt; of the People API Android Tutorial. Part 2 is where all this is put into action in code. However, I suggest you at least skim through this.&lt;/p&gt;
&lt;h2&gt;Two Different People API&lt;/h2&gt;
&lt;p&gt;Let&apos;s clear some misconceptions first. First, there&apos;s the &lt;a href=&quot;https://developers.google.com/+/mobile/android/people#before_you_begin&quot;&gt;Google+ People API&lt;/a&gt;. Those who have used Google+ library in Android, would be familiar. Now that is not the same as &lt;a href=&quot;https://developers.google.com/people/&quot;&gt;this&lt;/a&gt;, which is what I&apos;m talking about. Not the Google+ version. The difference in simple words is:  &lt;em&gt;People API (new)&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Denotes your Google contacts&lt;/li&gt;
&lt;li&gt;Your Contacts and Google+ data through one API.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Google+ People API&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Denotes Google+ users&lt;/li&gt;
&lt;li&gt;Only Google+ related data&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can refer the links above,  just in case I haven&apos;t convinced you enough. Ok, I&apos;m saying API too much. Let&apos;s get started?&lt;/p&gt;
&lt;h2&gt;Create a new project&lt;/h2&gt;
&lt;p&gt;Head over to &lt;a href=&quot;https://console.developers.google.com&quot;&gt;https://console.developers.google.com&lt;/a&gt; and create a new project.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./people-api-android-tutorial-1/create-new-project-google-api-console-420x185.png&quot; alt=&quot;create new project google api console&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Next, enable the People API.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./people-api-android-tutorial-1/enabled-People-API-e1460908911610-744x368.png&quot; alt=&quot;enabled People API&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Once you enable the People API, you&apos;d see that little warning about credentials. It authenticates our app to make API calls. So let&apos;s do that next.&lt;/p&gt;
&lt;h3&gt;Adding Credentials&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./people-api-android-tutorial-1/add-credentials-to-your-project-744x626.png&quot; alt=&quot;add credentials to your project&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./people-api-android-tutorial-1/create-an-OAuth-2-client-ID-744x814.png&quot; alt=&quot;create an OAuth 2 client ID&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Use Android&apos;s debug certificate for signing. Here&apos;s the command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;keytool -exportcert -alias androiddebugkey -keystore $HOME/.android/debug.keystore -list -v
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;$HOME/.android/debug.keystore&lt;/em&gt; is the default path on Mac. For windows, the debug.keystore can be found in your Android SDK folder.&lt;/p&gt;
&lt;p&gt;Successfully executing this will print your &lt;strong&gt;SHA-1&lt;/strong&gt; fingerprint key. You need it for generating credentials for an Android client. After configuring your credentials you will be prompted to download them as a JSON file. You don&apos;t have to download it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./people-api-android-tutorial-1/client-ID-Web-744x567.png&quot; alt=&quot;client ID Web&quot; title=&quot;Client ID for Web&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./people-api-android-tutorial-1/client-ID-android-744x548.png&quot; alt=&quot;Client ID for Android&quot; title=&quot;Client ID for Android&quot; /&gt;&lt;/p&gt;
&lt;p&gt;It&apos;s important that credentials are created for Android, and &lt;strong&gt;OAuth Client ID&lt;/strong&gt; for web. Once you&apos;ve created credentials for Android, do the same for web. You&apos;ll need your web&apos;s Client ID and Client Secret in the future. It might appear strange to add credentials for a Web client, for an Android app. It appears that we need credentials for BOTH Web and Android clients for it to work. However, within our Android app we&apos;ll only use keys from the Web client. Sound&apos;s weird right? Well that&apos;s how it works. Really hope Google would simply this in the future. So this is how my Credentials section in the API Manager is looking right now:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./people-api-android-tutorial-1/credentials-overview-744x210.png&quot; alt=&quot;credentials overview&quot; /&gt;&lt;/p&gt;
&lt;p&gt;If yours looks similar to this, then you&apos;re good to go. You can name both your clients anything you want. I&apos;ve stuck to the default names.&lt;/p&gt;
&lt;h2&gt;Enable Play Services for Android&lt;/h2&gt;
&lt;p&gt;To successfully link the People API and Play Services on our Android device, we&apos;ll be using Google Sign-in. Doing so, allows us to authenticate our requests which the API requires. Start by &lt;a href=&quot;https://developers.google.com/mobile/add?platform=android&amp;amp;cntapi=signin&amp;amp;cntapp=Default%20Demo%20App&amp;amp;cntpkg=com.google.samples.quickstart.signin&amp;amp;cnturl=https:%2F%2Fdevelopers.google.com%2Fidentity%2Fsign-in%2Fandroid%2Fstart%3Fconfigured%3Dtrue&amp;amp;cntlbl=Continue%20with%20Try%20Sign-In&quot;&gt;enabling Play Services&lt;/a&gt; for your newly created project.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./people-api-android-tutorial-1/enable-play-services-for-android-e1460908976246-744x394.png&quot; alt=&quot;enable play services for android&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Hit that huge blue button to proceed. In the next step, enable &lt;strong&gt;Google Sign-In&lt;/strong&gt;. Remember that &lt;strong&gt;SHA-1&lt;/strong&gt; fingerprint we got in the previous step? Add that same key here. Finally, generate your configuration file, &lt;strong&gt;google-services.json&lt;/strong&gt; and download it. It includes all the credential details you generated in the previous step. Neat!&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Let&apos;s take a breather here. Why did we do all this? I just want to use the People API. Is all this needed? If you&apos;re asking anything like these questions, here&apos;s the long story short. Using any of Google&apos;s API services requires authentication (OAuth). It basically involves an exchange of a token which validates against the requests you make. The Play Services are specific to Android OS. They have a super easy API client library to use. This is possible with the Play Services SDK installed by default on your Android device. Some of the Google APIs come along with Play Services, such as Google+, Analytics and Maps. Here&apos;s the &lt;a href=&quot;https://developers.google.com/android/guides/setup#add_google_play_services_to_your_project&quot;&gt;list of APIs&lt;/a&gt; bundled with Play Services. All the other Google APIs can be found &lt;a href=&quot;https://developers.google.com/apis-explorer/#p/&quot;&gt;here&lt;/a&gt;. What we&apos;re doing is, using Play Services to Sign-in. Then obtain a token from here and access a Google API (People API). We&apos;re going to integrate the two. Here&apos;s how both the mechanisms work:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./people-api-android-tutorial-1/image00.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I hope that was clear enough for you. A more detailed explanation of integrating the two, can be found in the &lt;a href=&quot;http://android-developers.blogspot.in/2016/02/using-credentials-between-your-server.html&quot;&gt;Android developer&apos;s blog post&lt;/a&gt;. You can ignore the code snippets there. It&apos;ll be covered in Part 2 of this post.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Great! Now we have a ready project created in Google API Console. We&apos;ve created credentials for both Android and Web clients, and enabled Play Services with Google Sign-in. With all the needed configuration in place, we&apos;re ready to integrate this into our Android app. Head over to &lt;a href=&quot;https://blog.iamsuleiman.com/people-api-android-tutorial-2/&quot;&gt;part 2&lt;/a&gt;!&lt;/p&gt;
</content:encoded></item><item><title>People API Android Tutorial – Part 2</title><link>https://blog.iamsuleiman.com/people-api-android-tutorial-2/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/people-api-android-tutorial-2/</guid><description>Let&apos;s look at using the People API in our Android app. We will see how it allows us to pull data from contacts, as well as data from their G+ profiles</description><pubDate>Tue, 19 Apr 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Let&apos;s look at using the People API in our Android app. We will see how it allows us to pull data from contacts, as well as data from their G+ profiles. All through the People API alone.&lt;/p&gt;
&lt;h2&gt;Recap&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/people-api-android-tutorial-1/&quot;&gt;Part 1&lt;/a&gt; covered configuring a project via the Google API Console. We created credentials for Android and Web client. Next, we enabled Play Services for our project and downloaded a configuration file for the same. In part 2, we&apos;ll look at its implementation.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Preparing your App&lt;/h2&gt;
&lt;p&gt;Start by adding these to your Android app&apos;s Gradle dependencies:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;repositories {
    mavenCentral()
}

dependencies {
    ...
    compile &apos;com.google.android.gms:play-services-plus:8.4.0&apos;
    compile &apos;com.google.android.gms:play-services-auth:8.4.0&apos;
    compile &apos;com.google.api-client:google-api-client:1.21.0&apos;
    //  People API
    compile &apos;com.google.apis:google-api-services-people:v1-rev2-1.21.0&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Don&apos;t forget to add an Internet permission in your &lt;strong&gt;AndroidManifest.xml&lt;/strong&gt; file.&lt;/p&gt;
&lt;h3&gt;Client ID and Secret&lt;/h3&gt;
&lt;p&gt;Take a look at your Web Client credentials in your Google API Console. You will notice a Client ID and Client Secret. Keep in mind we need these from the Web client, not Android. For the sake of this tutorial and complexity, I will simply add the Web Client&apos;s Client ID and Secret to my &lt;strong&gt;strings.xml&lt;/strong&gt; file. Feel free to do the same, but remember that &lt;strong&gt;google-services.json&lt;/strong&gt; file you downloaded in Part 1? Preferably, you must to add the file to your Android Studio project. Then JSON parse that file contents and fetch your keys from that.&lt;/p&gt;
&lt;h2&gt;Adding Google Sign in&lt;/h2&gt;
&lt;p&gt;Next, we&apos;ll add a Google Sign in. By signing in, we can obtain a valid access token from our registered Google account. In turn, this token will help us access the People API. Start by adding the Sign in button widget in your XML layout:&lt;/p&gt;
&lt;p&gt;When we perform a sign in, we need to tell Play Services, what APIs and Scopes we&apos;re requesting.&lt;/p&gt;
&lt;h3&gt;GoogleSignInOptions&lt;/h3&gt;
&lt;p&gt;Notice the Scopes I&apos;m requesting here. With the People API, for the sake of demonstration I&apos;m happy with two.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;GoogleSignInOptions signInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
             // The serverClientId is an OAuth 2.0 web client ID
             .requestServerAuthCode(getString(R.string.clientID))
             .requestEmail()
             .requestScopes(new Scope(Scopes.PLUS_LOGIN),
                     new Scope(PeopleScopes.CONTACTS_READONLY),
                     new Scope(PeopleScopes.USER_PHONENUMBERS_READ))
             .build();
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;GoogleApiClient&lt;/h4&gt;
&lt;p&gt;Next we build an instance of the GoogleApiClient. This helps handling whether Play Services exists on our app and handles it accordingly.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// To connect with Google Play Services and Sign In
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .enableAutoManage(this, this)
                .addOnConnectionFailedListener(this)
                .addConnectionCallbacks(this)
                .addApi(Auth.GOOGLE_SIGN_IN_API, signInOptions)
                .build();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While you&apos;re at it, you can implement the &lt;strong&gt;GoogleApiClient.OnConnectionFailedListener&lt;/strong&gt; and &lt;strong&gt;GoogleApiClient.ConnectionCallbacks&lt;/strong&gt; interfaces. They&apos;re pretty handy! We won&apos;t take any chances with whether the needed APIs are available or not. So let&apos;s add a safety check if the connection fails. This code snippet fetches the error message and displays it in a dialog.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    GoogleApiAvailability mGoogleApiAvailability = GoogleApiAvailability.getInstance();
    Dialog dialog = mGoogleApiAvailability.getErrorDialog(this, connectionResult.getErrorCode(), RC_API_CHECK);
    dialog.show();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Enable your API Client connection in the &lt;strong&gt;onStart()&lt;/strong&gt; method.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override
  protected void onStart() {
      super.onStart();
      mGoogleApiClient.connect();
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Google Sign-in Click Listener&lt;/h4&gt;
&lt;p&gt;Lastly, we define the on-click action for our Google Sign In button.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override
   public void onClick(View v) {
       switch (v.getId()) {
           case R.id.main_googlesigninbtn:
               getIdToken();
               break;
       }
   }

   private void getIdToken() {
       // Shows an account picker to let the user choose a Google account from the device.
       // If the GoogleSignInOptions only asks for IDToken and/or profile and/or email then no
       // consent screen will be shown here.
       Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
       startActivityForResult(signInIntent, RC_INTENT);
   }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note &lt;strong&gt;RC_INTENT&lt;/strong&gt; here. It&apos;s simply a request code, used to recognize the results returned from the sign-in. We can handle this in &lt;strong&gt;onActivityResult()&lt;/strong&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    switch (requestCode) {
        case RC_INTENT:
            GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);

            if (result.isSuccess()) {
                GoogleSignInAccount acct = result.getSignInAccount();
                Log.d(TAG, &quot;onActivityResult:GET_TOKEN:success:&quot; + result.getStatus().isSuccess());
                // This is what we need to exchange with the server.
                new PeoplesAsync().execute(acct.getServerAuthCode());

            } else {
                Log.d(TAG, result.getStatus().toString() + &quot;\nmsg: &quot; + result.getStatus().getStatusMessage());
            }
            break;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can verify the success of the sign-in using &lt;strong&gt;GoogleSignInResult&lt;/strong&gt;. Use the result to fetch the server auth code. We now have what we need to authenticate our calls to the People API.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Finally, People API&lt;/h2&gt;
&lt;p&gt;I can&apos;t believe it took us one and a half posts to get to the actual thing! So without wasting time, let&apos;s start implementing this. Here&apos;s 3 things we need to do:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Exchange the server auth code we got for a token response&lt;/li&gt;
&lt;li&gt;Create a credential using the response&lt;/li&gt;
&lt;li&gt;Use the credentials to obtain an instance of People API&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Simple? The code snippet below demonstrates this.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static People setUp(Context context, String serverAuthCode) throws IOException {
       HttpTransport httpTransport = new NetHttpTransport();
       JacksonFactory jsonFactory = JacksonFactory.getDefaultInstance();

       // Redirect URL for web based applications.
       // Can be empty too.
       String redirectUrl = &quot;urn:ietf:wg:oauth:2.0:oob&quot;;

       // STEP 1
       GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest(
               httpTransport,
               jsonFactory,
               context.getString(R.string.clientID),
               context.getString(R.string.clientSecret),
               serverAuthCode,
               redirectUrl).execute();

       // STEP 2
       GoogleCredential credential = new GoogleCredential.Builder()
               .setClientSecrets(context.getString(R.string.clientID), context.getString(R.string.clientSecret))
               .setTransport(httpTransport)
               .setJsonFactory(jsonFactory)
               .build();

       credential.setFromTokenResponse(tokenResponse);
 
       // STEP 3
       return new People.Builder(httpTransport, jsonFactory, credential)
               .setApplicationName(APPLICATION_NAME)
               .build();
   }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pass in the server auth code you obtained from the sign-in result in the previous step. Again, notice how I&apos;m referencing my Client ID and Client Secret here. They are simply strings. But you must JSON parse them from the &lt;strong&gt;google-services.json&lt;/strong&gt; file. &lt;strong&gt;NOTE:&lt;/strong&gt; Use the Client ID and Secret of your Web client and NOT Android Client!&lt;/p&gt;
&lt;h3&gt;Calling it in&lt;/h3&gt;
&lt;p&gt;With the above &lt;strong&gt;setUp()&lt;/strong&gt; method done, we just need to call it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;People peopleService = setUp(MainActivity.this, serverAuthCode);

ListConnectionsResponse response = peopleService.people().connections()
                                   .list(&quot;people/me&quot;)
                        .setRequestMaskIncludeField(&quot;person.names,person.emailAddresses,person.phoneNumbers&quot;)
                                   .execute();

List connections = response.getConnections();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&apos;re pretty much done! We now have a list of our connections, and we get get a lot of information from that. You would have noticed I requested Scopes for contacts and their phone numbers during Sign-in. So let&apos;s see an example for fetching phone numbers. &lt;strong&gt;NOTE:&lt;/strong&gt; Use must the &lt;strong&gt;setRequestMaskIncludeField()&lt;/strong&gt; method to specify which data fields you want to request. Omitting this &apos;ideally&apos; means the API will return ALL data sets under the sun. But that doesn&apos;t happen, and is a known issue. Check this &lt;a href=&quot;https://stackoverflow.com/questions/35604406/retrieving-information-about-a-contact-with-google-people-api-java#&quot;&gt;SO post&lt;/a&gt; for more. Here&apos;s the &lt;a href=&quot;https://developers.google.com/people/v1/how-tos/authorizing#connection-scopes&quot;&gt;full list&lt;/a&gt; of People API scopes. Once you fetch the connections into a list, simply iterate through it to fetch data.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for (Person person : connections) {
    if (!person.isEmpty()) {
       List phoneNumbers = person.getPhoneNumbers();

       if (phoneNumbers != null)
          for (PhoneNumber phoneNumber : phoneNumbers)
               Log.d(TAG, &quot;phone: &quot; + phoneNumber.getValue());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hope the code there is self-explanatory. Fetching the phone numbers from a person, is yet another list. So we simply iterate down another level to fetch the phone numbers. Simple as that. If you want the email IDs, it is &lt;code&gt;person.getEmailAddresses()&lt;/code&gt;. You&apos;d be surprised to know the rich data that the People API allows you to access. Here&apos;s the &lt;a href=&quot;https://developers.google.com/people/api/rest/v1/people#resource-person&quot;&gt;complete list&lt;/a&gt; for your reference. Just keep in mind good UX and wrap all these calls in an AsyncTask. Show a progress indicator if it takes too long to load.&lt;/p&gt;
&lt;h2&gt;Final Output&lt;/h2&gt;
&lt;p&gt;Here&apos;s a little demo of how the API works.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/people-api-android-tutorial-2/people-api-demo.gif&quot; alt=&quot;people api demo&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Ideally upon first launch, the app will display an account picker and then request permissions. Of course I&apos;m only displaying the name from the People API. But I&apos;m printing the rest to the logs. You can check out the source code for this on &lt;a href=&quot;https://github.com/Suleiman19/People-API-App/blob/master/app/src/main/java/com/grafixartist/peoples/MainActivity.java&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Wrapping it up&lt;/h2&gt;
&lt;p&gt;That&apos;s it for this two-part post on the People API. Hope you&apos;ve got a good feel about how powerful the API can be. In fact Google plans to completely replace the Contacts API with People API in the near future. So now&apos;s a really good time to migrate! Plus, you can even query one&apos;s Google+ related data from this API. While configuration might seem to be a handful, the long-term usefulness of the API far outweighs it. So what do you think? Know anything important I might have missed? Any cool features it has, that I&apos;m not aware of? Drop &apos;em in the comments below!&lt;/p&gt;
</content:encoded></item><item><title>Bottom Navigation Bar Android Tutorial</title><link>https://blog.iamsuleiman.com/bottom-navigation-bar-android-tutorial/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/bottom-navigation-bar-android-tutorial/</guid><description>One of the newest additions to the Material Design is the Bottom Navigation Bar. Its like the TabBar you see on iOS, and similar in functionality too.</description><pubDate>Tue, 22 Mar 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;One of the newest additions to the Material Design is the Bottom Navigation Bar. Its like the TabBar you see on iOS, and similar in functionality too.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./bottom-navigation-bar-android-tutorial/android-bottom-navigation-tabs-e1458558718473.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Android Bottom Navigation&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./bottom-navigation-bar-android-tutorial/facebook-iOS-app-tabbar-e1458558782433.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Facebook iOS App&lt;/p&gt;
&lt;p&gt;Before getting to the tutorial, let&apos;s get to know what Bottom Navigation is. Also let&apos;s narrow down on the best scenarios to use it.&lt;/p&gt;
&lt;h2&gt;What is Bottom Navigation?&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Bottom navigation bars make it easy to explore and switch between top-level views in a single tap. - &lt;a href=&quot;https://www.google.com/design/spec/components/bottom-navigation.html#bottom-navigation-usage&quot;&gt;Material Design spec&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This helps developers opt for Bottom Navigation, instead of a Navigation Drawer.&lt;/p&gt;
&lt;p&gt;If you have about four top-level navigation items, its ideal to use Bottom Navigation. Otherwise, go for a Navigation Drawer. We don’t want the Bottom Navigation looking too crowded now, do we?&lt;/p&gt;
&lt;p&gt;This was already common for iOS apps. But now, a lot of Android apps have started adapting this. To name a few, the YouTube app recently made the switch.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./bottom-navigation-bar-android-tutorial/youtube-bottom-navigation.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Bottom Navigation was recently adopted by the Android Youtube app&lt;/p&gt;
&lt;h3&gt;When to use?&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;A Bottom Navigation is best used when you have three to five top-level navigation items of similar importance.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Until now, the default, go-to navigation solution is the &lt;a href=&quot;https://blog.iamsuleiman.com/easy-navigation-drawer-with-design-support-library/&quot;&gt;Navigation Drawer&lt;/a&gt;. Would you agree?&lt;/p&gt;
&lt;p&gt;Grab all your screens, throw them in the Navigation Drawer and we&apos;re done. I don&apos;t blame you. Once upon a time, I was guilty of the same.&lt;/p&gt;
&lt;p&gt;For just 4 navigation screens, would you use an entire Navigation Drawer for it? Besides, that huge side menu is hidden away by a tiny hamburger menu.&lt;/p&gt;
&lt;p&gt;Think of the benefits a Bottom Navigation provides:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;always visible&lt;/strong&gt; - its omnipresent no matter which of the 4 screens you visit&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;simpler&lt;/strong&gt; - lesser the options, easier to remember&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So given all that, in such a scenario, a Bottom Navigation will serve you the best.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A simpler way to look at it&lt;/strong&gt; –&lt;/p&gt;
&lt;p&gt;If all that seems too complex, then just keep the number of navigation screens in mind.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;2 screens&lt;/em&gt; - &lt;a href=&quot;https://blog.iamsuleiman.com/material-design-tabs-with-android-design-support-library/&quot;&gt;Tabs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;3 to 5 screens&lt;/em&gt; - Bottom Navigation&lt;/li&gt;
&lt;li&gt;&lt;em&gt;5 and above&lt;/em&gt; - Navigation Drawer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Easy enough? Now let&apos;s move on.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;I must admit the Bottom Navigation looks pretty cool. I noticed Aurelien Hubert has a fancy Bottom Navigation &lt;a href=&quot;https://github.com/aurelhubert/ahbottomnavigation&quot;&gt;library&lt;/a&gt;. So let’s use that for this tutorial.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
Android Design Support Library provides a Bottom Navigation Bar too. But compared to this one, what we can do with it is currently limited. Hence, to know what all is possible with the Bottom Bar, we’ll go with Hubert’s library.&lt;/p&gt;
&lt;p&gt;However, if you want to use the Design Support Library instead, &lt;a href=&quot;https://blog.iamsuleiman.com/using-bottom-navigation-view-android-design-support-library/&quot;&gt;this tutorial&lt;/a&gt;’s got you covered.&lt;/p&gt;
&lt;p&gt;But seriously, read this first. This one’s got all the bells and whistles!&lt;/p&gt;
&lt;p&gt;First, start by adding the library’s dependency to your **app/**&lt;strong&gt;build.gradle&lt;/strong&gt; file.&lt;/p&gt;
&lt;p&gt;dependencies {
compile &apos;com.aurelhubert:ahbottomnavigation:0.1.3&apos;
}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
I hope your app supports &lt;strong&gt;minSdk &amp;gt;14&lt;/strong&gt;. If not, make sure you do, because this library supports 14 and above only. Seriously, why are you supporting 0.99% of the (ancient) devices!?&lt;/p&gt;
&lt;h3&gt;Adding Bottom Navigation to Layout&lt;/h3&gt;
&lt;p&gt;Make sure your parent layout is a &lt;code&gt;CoordinatorLayout&lt;/code&gt;. This ensures the Bottom Navigation behaves correctly with &lt;a href=&quot;https://blog.iamsuleiman.com/material-design-snackbar/&quot;&gt;&lt;code&gt;Snackbar&lt;/code&gt;&lt;/a&gt; and FAB.&lt;/p&gt;
&lt;p&gt;&amp;lt;android.support.design.widget.CoordinatorLayout
xmlns:android=&quot;&lt;a href=&quot;http://schemas.android.com/apk/res/android&quot;&gt;http://schemas.android.com/apk/res/android&lt;/a&gt;&quot;
xmlns:app=&quot;&lt;a href=&quot;http://schemas.android.com/apk/res-auto&quot;&gt;http://schemas.android.com/apk/res-auto&lt;/a&gt;&quot;
xmlns:tools=&quot;&lt;a href=&quot;http://schemas.android.com/tools&quot;&gt;http://schemas.android.com/tools&lt;/a&gt;&quot;
android:id=&quot;@+id/coordinator&quot;
android:layout_width=&quot;match_parent&quot;
android:layout_height=&quot;match_parent&quot;&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;android.support.design.widget.AppBarLayout
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;wrap_content&quot;&amp;gt;

    &amp;lt;android.support.v7.widget.Toolbar
        android:id=&quot;@+id/toolbar&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;?attr/actionBarSize&quot;
        android:background=&quot;?attr/colorPrimary&quot;/&amp;gt;

&amp;lt;/android.support.design.widget.AppBarLayout&amp;gt;

&amp;lt;FrameLayout
    android:id=&quot;@+id/frame&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    app:layout_behavior=&quot;@string/appbar_scrolling_view_behavior&quot;
    tools:background=&quot;#EFEFEF&quot;/&amp;gt;

&amp;lt;com.aurelhubert.ahbottomnavigation.AHBottomNavigation
    android:id=&quot;@+id/bottom_navigation&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;wrap_content&quot;
    android:layout_gravity=&quot;bottom&quot;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/android.support.design.widget.CoordinatorLayout&amp;gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;FrameLayout&lt;/code&gt; with ID &lt;em&gt;@+id/&lt;strong&gt;frame&lt;/strong&gt;&lt;/em&gt; is the placeholder UI to load our &lt;code&gt;Fragment&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Moving onto Java&lt;/h3&gt;
&lt;p&gt;Each Bottom Navigation bar item denotes a different color. For demonstration purposes, each item click will change the &lt;code&gt;Fragment&lt;/code&gt;’s view color. But ideally, you’ll want to load a different &lt;code&gt;Fragment&lt;/code&gt; for each item.&lt;/p&gt;
&lt;p&gt;Initializing and using the Bottom Navigation is easy as one two three. I ain’t even kidding. See for yourself!&lt;/p&gt;
&lt;h4&gt;1. Create your Items&lt;/h4&gt;
&lt;p&gt;There are different constructors you can use to define your Bottom Navigation items.&lt;/p&gt;
&lt;p&gt;At the least, you must provide a title and icon. In other words, a &lt;code&gt;String&lt;/code&gt; and &lt;code&gt;Drawable&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Both parameters can be hardcoded Strings. But for the sake of good practice, lets reference both from XML resources.&lt;/p&gt;
&lt;p&gt;AHBottomNavigationItem item1 = new AHBottomNavigationItem(R.string.bottomnav_title_0, R.drawable.ic_map_24dp);&lt;/p&gt;
&lt;h4&gt;2. Add Bottom Navigation items&lt;/h4&gt;
&lt;p&gt;Once you’ve defined the number of items, its time to add them to the Bottom Navigation.&lt;/p&gt;
&lt;p&gt;Use the following method to do so.&lt;/p&gt;
&lt;p&gt;bottomNavigation.addItem(item1);&lt;/p&gt;
&lt;h4&gt;3. Set Listener&lt;/h4&gt;
&lt;p&gt;Finally, you need to listen to item clicks. So add the following to your &lt;code&gt;Fragment&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;bottomNavigation.setOnTabSelectedListener(new AHBottomNavigation.OnTabSelectedListener() {
@Override
public void onTabSelected(int position, boolean wasSelected) {
fragment.updateColor(Color.parseColor(colors[position]));
}
});&lt;/p&gt;
&lt;p&gt;I have a tiny card layout centered in my &lt;code&gt;Fragment&lt;/code&gt; layout. Depending on the item click, I change its color.&lt;/p&gt;
&lt;p&gt;Also, don’t forget to set your default item. This item depicts the default (home) screen which people will see.&lt;/p&gt;
&lt;p&gt;// Setting the very 1st item as home screen.&lt;br /&gt;
bottomNavigation.setCurrentItem(0);&lt;/p&gt;
&lt;p&gt;Ideally, you’d want to change the &lt;code&gt;Fragment&lt;/code&gt; here. The same way when &lt;a href=&quot;https://blog.iamsuleiman.com/easy-navigation-drawer-with-design-support-library/&quot;&gt;creating a Navigation Drawer in Android&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Styling Bottom Navigation&lt;/h2&gt;
&lt;p&gt;Off the bat, the library provides considerable styling options. But after recent updates, there has been a lot more.&lt;/p&gt;
&lt;p&gt;Some of these additions include notification badges and coordinating behaviors. It also includes &lt;a href=&quot;https://blog.iamsuleiman.com/quick-return-pattern-with-android-design-support-library/&quot;&gt;on-scroll Quick Return pattern&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Its all that one could ever want with the Bottom Navigation. This library is much more feature-rich than &lt;a href=&quot;https://blog.iamsuleiman.com/using-bottom-navigation-view-android-design-support-library/&quot;&gt;what Android Design Support Library offers&lt;/a&gt;. So if you want more customization options and more control, you know what to use.&lt;/p&gt;
&lt;p&gt;Before we get to that, here’s a heads-up. We’ll be using and referencing a lot of colors. Normally, we reference colors in Android like this:&lt;/p&gt;
&lt;p&gt;ContextCompat.getColor(context, R.id.yourcolor);&lt;/p&gt;
&lt;p&gt;Now I’m no fan of writing such a lengthy line for fetching a simple color resource.&lt;/p&gt;
&lt;p&gt;So I’ll write a simple method that shortens what I have to type.&lt;/p&gt;
&lt;p&gt;private int fetchColor(@ColorRes int color) {
return ContextCompat.getColor(this, color);
}&lt;/p&gt;
&lt;p&gt;Great! From now on I don’t  have to write long lines. This simple method call will do to fetch my color resource.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;
Hiding the complexities of a system by providing a simpler interface is known as the &lt;a href=&quot;https://www.tutorialspoint.com/design_pattern/facade_pattern.htm&quot;&gt;Facade Design Pattern&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;With that out of the way, let’s look at implementing all the possible styling options.&lt;/p&gt;
&lt;h3&gt;Simple Theming&lt;/h3&gt;
&lt;p&gt;At the most basic level, the Bottom Navigation requires these attributes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Default background color&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Accent color&lt;/em&gt; - highlights active items&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Inactive color&lt;/em&gt; - (you guessed it!) color for inactive items&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;bottomNavigation.setDefaultBackgroundColor(Color.WHITE);
bottomNavigation.setAccentColor(fetchColor(R.color.yourAccentColor));
bottomNavigation.setInactiveColor(fetchColor(R.color.yourInactiveColor));&lt;/p&gt;
&lt;p&gt;With such basic styling, you can expect your Bottom Navigation to look like this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./bottom-navigation-bar-android-tutorial/bottom_navigation_bar_basic_styling.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Bottom Navigation with basic styling&lt;/p&gt;
&lt;h3&gt;Color Ripple Effects&lt;/h3&gt;
&lt;p&gt;You can take styling a step further by using a color ripple.&lt;/p&gt;
&lt;p&gt;Yes, I’m talking about this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/bottom-navigation-bar-android-tutorial/bottom_navigation_color_ripple.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Bottom Navigation with Color Ripple&lt;/p&gt;
&lt;p&gt;The good news is that its easy to enable a colored ripple.&lt;/p&gt;
&lt;p&gt;//  Enables color Reveal effect
bottomNavigation.setColored(true);
// Colors for selected (active) and non-selected items (in color reveal mode).
bottomNavigation.setColoredModeColors(Color.WHITE,
fetchColor(R.color.bottomtab_item_resting));&lt;/p&gt;
&lt;p&gt;&lt;code&gt;setColoredModeColors()&lt;/code&gt; defines the colors for items when using color ripple.&lt;/p&gt;
&lt;h3&gt;Text Labels&lt;/h3&gt;
&lt;p&gt;Here’s what the &lt;a href=&quot;https://material.io/guidelines/components/bottom-navigation.html#bottom-navigation-usage&quot;&gt;Material Design documentation&lt;/a&gt; tells us. If Bottom Navigation has:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;3 items&lt;/em&gt; - display icon and text always for all items&lt;/li&gt;
&lt;li&gt;&lt;em&gt;4-5 items&lt;/em&gt; - display text for active icon only and hide for inactive views&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, you might have a good guess on what I’m going to say next.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;“This is what the Material Design guidelines suggest, so let’s do just that”.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;But this time I won’t. I disagree, and so should you. I’ll tell you why.&lt;/p&gt;
&lt;h4&gt;The Material Design guidelines aren’t always right&lt;/h4&gt;
&lt;p&gt;Whether you have 3 or 5 items in your Bottom Navigation, &lt;strong&gt;always show text labels!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;By doing so, you’ll avoid the &lt;a href=&quot;https://medium.freecodecamp.com/material-design-and-the-mystery-meat-navigation-problem-65425fb5b52e#.1ty8v8bst&quot;&gt;mystery meat navigation problem that plagues Material Design&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Buttons or links that don’t explain to you what they do. Instead, you have to click on them to find out&lt;/p&gt;
&lt;p&gt;Mystery Meat Navigation&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I’m sure we’ve all been victims of this at some point at least. We click on a button assuming it to do something, only for it to do something else entirely!&lt;/p&gt;
&lt;p&gt;So do yourselves, and your users a favor. Always, show text labels for your Bottom Navigation icons.&lt;/p&gt;
&lt;p&gt;bottomNavigation.setTitleState(AHBottomNavigation.TitleState.ALWAYS_SHOW);&lt;/p&gt;
&lt;p&gt;I did my part to give good UX. What about you?&lt;/p&gt;
&lt;h3&gt;Translucent Bottom Navigation&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./bottom-navigation-bar-android-tutorial/bottom_navigation_translucent.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Translucent Bottom Navigation&lt;/p&gt;
&lt;p&gt;First, you create an app Theme that supports translucent navigation.&lt;/p&gt;
&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;Next, in your &lt;em&gt;AndroidManifest.xml&lt;/em&gt;, apply this Theme to your Bottom Navigation &lt;code&gt;Activity&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;...

...&lt;/p&gt;
&lt;p&gt;Finally, the last step is to add one simple line to &lt;strong&gt;&lt;em&gt;YourActivity.java&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;bottomNavigation.setTranslucentNavigationEnabled(true);&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
Disable &lt;em&gt;Instant Run&lt;/em&gt; if you observe weird UI glitches. I&apos;ve disabled mine by default.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Behaviors&lt;/h3&gt;
&lt;p&gt;The library allows on-scroll animation for the Bottom Navigation Bar. It also supports a Translucent Theme for the same.&lt;/p&gt;
&lt;h4&gt;&apos;Quick Return&apos; Animation&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;A View can &lt;strong&gt;scroll off-screen&lt;/strong&gt; with the content and return when the user reverse scrolls.&lt;/p&gt;
&lt;p&gt;Quick Return&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/bottom-navigation-bar-android-tutorial/bottom_navigation_quick_return.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Hide on scroll - Quick Return&lt;/p&gt;
&lt;p&gt;This is a popular Animation pattern that helps maximize screen estate while scrolling. Usually the &lt;a href=&quot;https://blog.iamsuleiman.com/quick-return-pattern-with-android-design-support-library/&quot;&gt;Quick Return animation pattern is used for Toolbars&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The good new is, this library allows us to enable the same for Bottom Navigation. You just have to add this simple line.&lt;/p&gt;
&lt;p&gt;bottomNavigation.setBehaviorTranslationEnabled(true);&lt;/p&gt;
&lt;h4&gt;Translucent Navigation with Quick Return&lt;/h4&gt;
&lt;p&gt;Now you might get ambitious and want to combine both. A translucent Bottom Navigation and &lt;em&gt;Quick Return pattern&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;While I applaud your bravery, there’s a small hiccup in making both work together. You already might have set up a Translucent Navigation.&lt;/p&gt;
&lt;p&gt;But once you enable Quick Return, you might notice the scroll not behaving as expected. The &lt;code&gt;Toolbar&lt;/code&gt; might appear clipped. No amount of &lt;code&gt;fitsSystemWindows&lt;/code&gt; will help.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./bottom-navigation-bar-android-tutorial/translucent_bottom_navigation_toolbar_clipping.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Toolbar clipping with Translucent bar + quick return&lt;/p&gt;
&lt;p&gt;That’s the hiccup I’m talking about.&lt;/p&gt;
&lt;p&gt;But don’t worry. I’ll tell you how to fix this. Its not perfect, but it gets the job done.&lt;/p&gt;
&lt;p&gt;All you have to do is alter your &lt;code&gt;AppBarLayout&lt;/code&gt;. Add a &lt;code&gt;View&lt;/code&gt; as a child to your &lt;code&gt;AppBarLayout&lt;/code&gt;, above the &lt;code&gt;Toolbar&lt;/code&gt; View.. This &lt;code&gt;View&lt;/code&gt; should have a height equal to the &lt;em&gt;StatusBar&lt;/em&gt;, which is &lt;strong&gt;24dp&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&amp;lt;android.support.design.widget.CoordinatorLayout &amp;gt;
&amp;lt;android.support.design.widget.AppBarLayout&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  &amp;lt;LinearLayout
  android:orientation=&quot;vertical&quot;&amp;gt;
     &amp;lt;View
    android:layout_width=&quot;match_parent&quot;
       	android:layout_height=&quot;@dimen/statusBarSize&quot; /&amp;gt;

   	   &amp;lt;android.support.v7.widget.Toolbar
        	android:id=&quot;@+id/toolbar&quot;
       	android:layout_width=&quot;match_parent&quot;
       	android:layout_height=&quot;?attr/actionBarSize&quot;
       	android:background=&quot;?attr/colorPrimary&quot;/&amp;gt;
&amp;lt;/LinearLayout&amp;gt;

&amp;lt;/android.support.design.widget.AppBarLayout&amp;gt;

&amp;lt;FrameLayout
    android:id=&quot;@+id/frame&quot;
    app:layout_behavior=&quot;@string/appbar_scrolling_view_behavior&quot;/&amp;gt;

&amp;lt;com.aurelhubert.ahbottomnavigation.AHBottomNavigation
    android:id=&quot;@+id/bottom_navigation&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;wrap_content&quot;
    android:layout_gravity=&quot;bottom&quot;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/android.support.design.widget.CoordinatorLayout&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;&lt;code&gt;AppBarLayout&lt;/code&gt; is a vertical &lt;code&gt;LinearLayout&lt;/code&gt;&lt;/strong&gt; that determines scrolling behavior of its child Views.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/bottom-navigation-bar-android-tutorial/translucent_bottom_bar_quick_return.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Translucent bar with quick return&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Notification Badge&lt;/h3&gt;
&lt;p&gt;This again is simple. For the sake of demonstration, I’ll show you by creating a dummy notification.&lt;/p&gt;
&lt;h4&gt;Show notification&lt;/h4&gt;
&lt;p&gt;Let’s say I want to show a notification count of 1, for the last item. We can use the library&apos;s &lt;code&gt;AHNotification&lt;/code&gt; class for this.&lt;/p&gt;
&lt;p&gt;private void createFakeNotification() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
AHNotification notification = new AHNotification.Builder()
.setText(&quot;1&quot;)
.setBackgroundColor(Color.YELLOW)
.setTextColor(Color.BLACK)
.build();
// Adding notification to last item.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;           bottomNavigation.setNotification(notification, bottomNavigation.getItemsCount() - 1);

           notificationVisible = true;
       }
   }, 1000);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;The Builder allows us to customize the text, its color and the background. Then, remember to set that notification to the Bottom Navigation item.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./bottom-navigation-bar-android-tutorial/bottom_navigation_notification_badge.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Notification Badge&lt;/p&gt;
&lt;h4&gt;Remove notification&lt;/h4&gt;
&lt;p&gt;In the above code snippet, I used a boolean &lt;code&gt;notificationVisible.&lt;/code&gt; It tells us whether the notification badge is currently visible or not.&lt;/p&gt;
&lt;p&gt;A notification must be removed or dismissed once we tap the respective item. We can do this in 2 simple steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;detect the item click via &lt;code&gt;OnTabSelectedListener&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;check if notification is visible and remove it&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;bottomNavigation.setOnTabSelectedListener(new AHBottomNavigation.OnTabSelectedListener() {
@Override
public boolean onTabSelected(int position, boolean wasSelected) {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    //TODO: update Fragment here

         // remove notification badge
   int lastItemPos = bottomNavigation.getItemsCount() - 1;
         if (notificationVisible &amp;amp;&amp;amp; position == lastItemPos)
             bottomNavigation.setNotification(new AHNotification(), lastItemPos);

         return true;
     }
 });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To remove a notification, we set an EMPTY notification for that item. That is all there is to it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/bottom-navigation-bar-android-tutorial/bottom_navigation_notification_badge_dismiss.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Dismissing notification badge&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Managing Bottom Navigation with Fragments&lt;/h2&gt;
&lt;p&gt;It’s pretty obvious by now that each Bottom Bar’s item manages a &lt;code&gt;Fragment&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To put it in other words, you could say it’s similar to &lt;a href=&quot;https://blog.iamsuleiman.com/material-design-tabs-with-android-design-support-library/&quot;&gt;Material Tabs with a&lt;/a&gt; &lt;a href=&quot;https://blog.iamsuleiman.com/material-design-tabs-with-android-design-support-library/&quot;&gt;&lt;code&gt;ViewPager&lt;/code&gt;&lt;/a&gt;. Except you can’t swipe.&lt;/p&gt;
&lt;h3&gt;Maintaining Fragments with ViewPager&lt;/h3&gt;
&lt;p&gt;Now that we’ve decided on using a &lt;code&gt;ViewPager&lt;/code&gt; to handle our Fragments, we need to write an Adapter.&lt;/p&gt;
&lt;p&gt;For that, we have two choices:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html&quot;&gt;&lt;code&gt;FragmentPagerAdapter&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter.html&quot;&gt;&lt;code&gt;FragmentStatePagerAdapter&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now, depending on your use case, choosing between the two can make all the difference. But I’ll spare you all the rambling and state it simply.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Using a &lt;code&gt;**FragmentStatePagerAdapter**&lt;/code&gt; is more useful when there are a large number of pages. It holds on to much less memory associated with each visited page.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Okay, our Bottom Navigation has three items, but it can go up to five. So considering the extreme scenario, we can have five resource-heavy Fragments. So you can do your app a favour and use a &lt;code&gt;**FragmentStatePagerAdapter**&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But if you’re interested in knowing in depth, &lt;a href=&quot;https://stackoverflow.com/questions/18747975/difference-between-fragmentpageradapter-and-fragmentstatepageradapter&quot;&gt;this SO post&lt;/a&gt; has all the answers.&lt;/p&gt;
&lt;h4&gt;Creating the ViewPager Adapter&lt;/h4&gt;
&lt;p&gt;There’s a ‘smart’ implementation of &lt;code&gt;FragmentStatePagerAdapter&lt;/code&gt; that allows us to access already existing Fragments from the Adapter. So go ahead and grab it from this &lt;a href=&quot;https://gist.github.com/nesquena/c715c9b22fb873b1d259#file-smartfragmentstatepageradapter-java&quot;&gt;&lt;strong&gt;GitHub gist&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Next, to actually use this, we need to create our Adapter that extends &lt;code&gt;SmartFragmentStatePagerAdapter&lt;/code&gt;. So let’s call it &lt;strong&gt;&lt;em&gt;BottomBarAdapter&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;public class BottomBarAdapter extends SmartFragmentStatePagerAdapter {
private final List fragments = new ArrayList&amp;lt;&amp;gt;();&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public BottomBarAdapter(FragmentManager fragmentManager) {
    super(fragmentManager);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;// Our custom method that populates this Adapter with Fragments
&lt;strong&gt;public void addFragments(Fragment fragment) {
fragments.add(fragment);
}&lt;/strong&gt;
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override
public int getCount() {
    return fragments.size();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;Nothing fancy here. Just note the &lt;code&gt;List&amp;lt;Fragment&amp;gt;&lt;/code&gt; that our Adapter uses here.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
In future if you want to fetch a particular &lt;code&gt;Fragment&lt;/code&gt;, you can do it using &lt;code&gt;**pagerAdapter.getRegisteredFragment(position)**&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now that our Adapter is ready, we need to connect it to the &lt;code&gt;ViewPager&lt;/code&gt;. But wait. Not so fast!&lt;/p&gt;
&lt;p&gt;There is one tiny change we need to do to the &lt;code&gt;ViewPager&lt;/code&gt;. Swiping must be disabled.&lt;/p&gt;
&lt;h4&gt;Disable swiping on ViewPager&lt;/h4&gt;
&lt;p&gt;The easiest way is to create a custom &lt;code&gt;ViewPager&lt;/code&gt;. So let’s create a new class extending &lt;code&gt;ViewPager&lt;/code&gt;. I call it &lt;strong&gt;&lt;em&gt;NoSwipePager&lt;/em&gt;&lt;/strong&gt;, for the lack of a better name.&lt;/p&gt;
&lt;p&gt;public class NoSwipePager extends ViewPager {
private boolean enabled;&lt;/p&gt;
&lt;p&gt;public NoSwipePager(Context context, AttributeSet attrs) {
super(context, attrs);
this.enabled = true;
}&lt;/p&gt;
&lt;p&gt;@Override
public boolean onTouchEvent(MotionEvent event) {
if (this.enabled) {
return super.onTouchEvent(event);
}
return false;
}&lt;/p&gt;
&lt;p&gt;@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (this.enabled) {
return super.onInterceptTouchEvent(event);
}
return false;
}&lt;/p&gt;
&lt;p&gt;public void setPagingEnabled(boolean enabled) {
this.enabled = enabled;
}
}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
Make sure you reference &lt;em&gt;NoSwipePager&lt;/em&gt; in your XML layout instead of a regular &lt;code&gt;ViewPager&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Once, you initialize your &lt;code&gt;ViewPager&lt;/code&gt; in &lt;code&gt;Activity&lt;/code&gt;, you need to explicitly disable swiping. You can do it with a single line.&lt;/p&gt;
&lt;p&gt;viewPager.setPagingEnabled(false);&lt;/p&gt;
&lt;p&gt;With the previous step, our Adapter and &lt;code&gt;ViewPager&lt;/code&gt; is now ready to roll. The final step is to create our Fragments, then pass them to the Adapter and finally connect the Adapter with &lt;code&gt;ViewPager&lt;/code&gt;.&lt;/p&gt;
&lt;h5&gt;Connecting ViewPager with PagerAdapter&lt;/h5&gt;
&lt;p&gt;Let’s create a simple &lt;code&gt;Fragment&lt;/code&gt; called &lt;em&gt;DummyFragment&lt;/em&gt;. It accepts one argument “color”. Using a different color will tell us which &lt;code&gt;Fragment&lt;/code&gt;instance is shown when we use the Bottom Navigation.&lt;/p&gt;
&lt;p&gt;Once your &lt;code&gt;Fragment&lt;/code&gt; is ready, let’s get to completing our &lt;code&gt;ViewPager&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Set up &lt;code&gt;ViewPager&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;// init UI
viewPager.setPagingEnabled(false);&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Initialize PagerAdapter&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;pagerAdapter = new &lt;strong&gt;BottomBarAdapter&lt;/strong&gt;(getSupportFragmentManager());&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Create Fragments and add them to Adapter&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Bundle bundle = new Bundle();
bundle.putInt(&quot;color&quot;, color);&lt;/p&gt;
&lt;p&gt;DummyFragment fragment = new DummyFragment();
fragment.setArguments(bundle);&lt;/p&gt;
&lt;p&gt;pagerAdapter.addFragments(fragment);&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Finally, set the&lt;/strong&gt; &lt;code&gt;**ViewPager**&lt;/code&gt; &lt;strong&gt;Adapter&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;viewPager.setAdapter(pagerAdapter);&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Handling Click Events&lt;/h3&gt;
&lt;p&gt;Hang in there, we’re almost done!&lt;/p&gt;
&lt;p&gt;Since we disabled &lt;code&gt;ViewPager&lt;/code&gt; swiping, the only way to switch Fragments is by clicking the Bottom Navigation Items. So we need to manually handle those click events!&lt;/p&gt;
&lt;p&gt;Don’t worry, it’s dead simple. See for yourself!&lt;/p&gt;
&lt;p&gt;bottomNavigation.setOnTabSelectedListener(new AHBottomNavigation.OnTabSelectedListener() {
@Override
public boolean onTabSelected(int position, boolean wasSelected) {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;             **if (!wasSelected)**
                 **viewPager.setCurrentItem(position);**
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;return true;
}
});&lt;/p&gt;
&lt;p&gt;The click listener provides us a useful boolean that tells us if the current click is happening on an already selected item. So we simply need to change the &lt;code&gt;Fragment&lt;/code&gt; when this is NOT the case.&lt;/p&gt;
&lt;p&gt;That’s all there is to it.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Output&lt;/h2&gt;
&lt;p&gt;Just to give you a visual on how all that code works, here’s a GIF of everything put together.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/bottom-navigation-bar-android-tutorial/bottom-nav-bar-fragments-viewpager.gif&quot; alt=&quot;&quot; /&gt; *&lt;/p&gt;
&lt;h3&gt;Where to, from here?&lt;/h3&gt;
&lt;p&gt;The Bottom Navigation is the newest entry in Material Design. It pushes us to rethink our navigation structures.&lt;/p&gt;
&lt;p&gt;At first, it might be confusing. But I hope this post has helped clear the air.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SOURCE CODE:&lt;/strong&gt;&lt;br /&gt;
Available on &lt;a href=&quot;https://github.com/Suleiman19/Bottom-Navigation-Demo/blob/master/app/src/main/java/com/grafixartist/bottomnav/MainActivity.java&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;Other Options&lt;/strong&gt;&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/roughike/BottomBar&quot;&gt;&lt;strong&gt;Bottom Navigation Bar by roughike&lt;/strong&gt;&lt;/a&gt;&lt;br /&gt;
Clearly its the more popular one. But this library seems to work just as fine, so there’s no cause for alarm.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/using-bottom-navigation-view-android-design-support-library/&quot;&gt;&lt;strong&gt;Official Bottom Navigation by Design Support Library&lt;/strong&gt;&lt;br /&gt;
&lt;/a&gt;However, it is very limited in options in terms of styling and customization.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Wrap Up&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So what do you think about Bottom Navigation? It is very common in iOS but I’m excited to see how we’re going to use it in Android.&lt;/p&gt;
&lt;p&gt;A lot of Android apps have already adopted it (Instagram, Google+ and Quora to name a few). What about you? Let me know in the comments below.&lt;/p&gt;
</content:encoded></item><item><title>Bottom Sheet with Android Design Support Library</title><link>https://blog.iamsuleiman.com/bottom-sheet-android-design-support-library/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/bottom-sheet-android-design-support-library/</guid><description>Version 23.2 of the Android Support library is a huge update. The Design Support Library made Material Design easy. The new update made it a step easi</description><pubDate>Thu, 17 Mar 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Version 23.2 of the Android Support library is a huge update. The Design Support Library made Material Design easy. The new update made it a step easier by adding my personal favorite, Bottom Sheet! In this post, we&apos;ll look into making just that.&lt;/p&gt;
&lt;h2&gt;What&apos;s a Bottom Sheet?&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;A Bottom Sheet is a sheet of material that slides up from the bottom edge of the screen. Displayed only as a result of a user-initiated action, and can be swiped up to reveal additional content. It can be a temporary modal surface or a persistent structural element of an app. - &lt;a href=&quot;https://www.google.com/design/spec/components/bottom-sheets.html&quot;&gt;Material Design Spec&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here are some examples:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./bottom-sheet-android-design-support-library/bottom-sheets-storage.png&quot; alt=&quot;bottom sheets storage&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./bottom-sheet-android-design-support-library/bottom-sheets-maps.png&quot; alt=&quot;bottom sheets maps&quot; /&gt;&lt;/p&gt;
&lt;p&gt;We&apos;ll be making the exact Bottom Sheet on the right (excluding the map).&lt;/p&gt;
&lt;h2&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;Start off by updating your support libraries to &lt;a href=&quot;http://android-developers.blogspot.in/2016/02/android-support-library-232.html&quot;&gt;23.2.0&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dependencies {
    compile fileTree(include: [&apos;*.jar&apos;], dir: &apos;libs&apos;)
    compile &apos;com.android.support:appcompat-v7:23.2.0&apos;
    compile &apos;com.android.support:design:23.2.0&apos;
    ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also, for this tutorial I’m using:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Build Tools v 23.0.2&lt;/li&gt;
&lt;li&gt;Android Studio 1.5.1&lt;/li&gt;
&lt;li&gt;Gradle (Build Tools) 1.5.0&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you aren’t familiar with the Design Support Library, now is the time to do so. Read these Design Support Library tutorials:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/toolbar-animation-with-android-design-support-library/&quot;&gt;Toolbar Animation (Flexible Space with Image)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/material-design-tabs-with-android-design-support-library/&quot;&gt;Material Design Tabs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/easy-navigation-drawer-with-design-support-library/&quot;&gt;Easy Material Design Navigation Drawer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Adding a Bottom Sheet via XML&lt;/h2&gt;
&lt;p&gt;For those familiar, we include our scrollable view within CoordinatorLayout, below AppBarLayout in XML. To include a Bottom Sheet, we add it below our scrollable view. &lt;strong&gt;NOTE:&lt;/strong&gt; The Bottom Sheet does not use any special tag. It is just a NestedScrollView using a &lt;a href=&quot;http://developer.android.com/reference/android/support/design/widget/CoordinatorLayout.Behavior.html&quot;&gt;Behavior&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For the sake of clarity, you might want to include the Bottom Sheet XML via a separate file. To keep it simple, I&apos;ve only included the XML&apos;s hierarchy. But here&apos;s my complete &lt;a href=&quot;https://github.com/Suleiman19/Android-Material-Design-for-pre-Lollipop/blob/master/MaterialSample/app/src/main/res/layout/activity_gmail_style.xml&quot;&gt;layout&lt;/a&gt;. Note the &lt;strong&gt;layout_behavior&lt;/strong&gt; attribute for the NestedScrollView. It refers to the &lt;strong&gt;BottomSheetBehavior&lt;/strong&gt; provided by the Design Support Library. In this way, we’re telling CoordinatorLayout we want NestedScrollView to behave like a Bottom Sheet. By default, only a part of the Bottom Sheet is visible. We drag to expand, and continue scrolling. Use &lt;strong&gt;behavior_peekHeight&lt;/strong&gt; to define how much of the Bottom Sheet you want visible. Yep, that&apos;s all you pretty much need to get Bottom Sheet working. Just pure XML. This is what the Design Support Library has been about. Easy Material Design. So far, here&apos;s what we got.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/bottom-sheet-android-design-support-library/bottom-sheets-base.gif&quot; alt=&quot;bottom sheets base&quot; /&gt;&lt;/p&gt;
&lt;p&gt;But I&apos;m sure we&apos;re not here for just that? What if you want to listen to state changes? The folks at Android figured you&apos;d want to. So they provided a set of neat flags. Sweet!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Listening to Bottom Sheet state changes&lt;/h2&gt;
&lt;p&gt;If you read the official blog post about 23.2, you&apos;d notice the Google Maps Bottom Sheet. The Floating Action Button there, caught my eye. Its a perfect UI element to demonstrate the callbacks.&lt;/p&gt;
&lt;h3&gt;Action Plan&lt;/h3&gt;
&lt;p&gt;Here&apos;s what we&apos;re going to do. Let the &lt;a href=&quot;https://www.google.com/design/spec/components/buttons-floating-action-button.html&quot;&gt;Floating Action Button&lt;/a&gt; (FAB), be visible when the Bottom Sheet is resting (not expanded). It becomes invisible once the Bottom Sheet expands. We&apos;ll handle FAB&apos;s visiblity with a neat grow / shrink animation.&lt;/p&gt;
&lt;h4&gt;Grow / Shrink Animation&lt;/h4&gt;
&lt;p&gt;These animations are defined in XML. You can get the animations from &lt;a href=&quot;https://github.com/Suleiman19/Android-Material-Design-for-pre-Lollipop/tree/master/MaterialSample/app/src/main/res/anim&quot;&gt;here&lt;/a&gt;. Then simply reference these animations in your Activity like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Animation growAnimation = AnimationUtils.loadAnimation(this, R.anim.grow);
Animation shrinkAnimation = AnimationUtils.loadAnimation(this, R.anim.shrink);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Listening to State Changes&lt;/h3&gt;
&lt;p&gt;Now, onto the real deal. First, reference the Bottom Sheet from your CoordinatorLayout.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CoordinatorLayout coordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinator);
View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet);

BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Don&apos;t forget to reference your FAB.  Notice that we&apos;ve also referenced the BottomSheet&apos;s Behavior. This is needed to set the callback. Attach a BottomSheetCallback() to your behavior object. It provides 2 methods to override:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;onStateChanged()&lt;/li&gt;
&lt;li&gt;onSlide()&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;onStateChanged()&lt;/h4&gt;
&lt;p&gt;There are 5 flags in total:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;STATE_DRAGGING: intermediate state while the user is dragging the bottom sheet up or down&lt;/li&gt;
&lt;li&gt;STATE_COLLAPSED: default state&lt;/li&gt;
&lt;li&gt;STATE_EXPANDED: fully expanded state of the bottom sheet.&lt;/li&gt;
&lt;li&gt;STATE_HIDDEN: allows users to swipe down on the bottom sheet to completely hide it. Disabled by default&lt;/li&gt;
&lt;li&gt;STATE_SETTLING: brief time between when the View is released and settling into its final position&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Only the first 3, among 5 is what we need. Your onStateChanged() method will look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
          @Override
          public void onStateChanged(@NonNull View bottomSheet, int newState) {

              switch (newState) {
                  case BottomSheetBehavior.STATE_DRAGGING:
                      if (showFAB)
                          fab.startAnimation(shrinkAnimation);
                      break;

                  case BottomSheetBehavior.STATE_COLLAPSED:
                      showFAB = true;
                      fab.setVisibility(View.VISIBLE);
                      fab.startAnimation(growAnimation);
                      break;

                  case BottomSheetBehavior.STATE_EXPANDED:
                      showFAB = false;
                      break;
              }
          }
        ...
      });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While the Bottom Sheet is dragged, we want to shrink the FAB. STATE_COLLAPSED is the default resting position of the bottom sheet. This is where we want our FAB to appear with a grow animation. &lt;strong&gt;showFAB&lt;/strong&gt; is a Boolean that tracks if the FAB needs to be shown or not while dragged. &lt;strong&gt;ALTERNATE APPROACH:&lt;/strong&gt; Here&apos;s another way to do the FAB animation. Adjust the rate of growing / shrinking depending on the rate of the Bottom Sheet&apos;s drag. Grow if you drag down, shrink if you drag up. I leave that for you to try. With all this in place, lets see how our Bottom Sheet looks now.&lt;/p&gt;
&lt;h2&gt;Final Output&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/bottom-sheet-android-design-support-library/bottom-sheets-animation.gif&quot; alt=&quot;bottom sheets animation&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Our Bottom Sheet sure does have some life now doesn&apos;t it? With the help of its callbacks, we were also able to do this nice little grow / shrink animation. The new Android Support Library 23.2 is a nice update, with Bottom Sheets added to it, just made it better. &lt;strong&gt;SOURCE CODE:&lt;/strong&gt; &lt;a href=&quot;https://github.com/Suleiman19/Android-Material-Design-for-pre-Lollipop/blob/master/MaterialSample/app/src/main/java/com/suleiman/material/activities/GmailStyleActivity.java&quot;&gt;GitHub&lt;/a&gt; What designs did you come up with? Drop &apos;em in the comments below. Or share the post if you liked it!&lt;/p&gt;
</content:encoded></item><item><title>Android SQLite Database Tutorial with Sugar ORM</title><link>https://blog.iamsuleiman.com/android-sqlite-database-tutorial-sugar-orm/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/android-sqlite-database-tutorial-sugar-orm/</guid><description>SQLite database is one way to store your app’s data locally in Android. In this Android SQLite Database tutorial, I’m here to show you an easier way t</description><pubDate>Mon, 22 Feb 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;SQLite database is one way to store your app’s data locally in Android. In this Android SQLite Database tutorial, I’m here to show you an easier way to it. Using &lt;a href=&quot;http://satyan.github.io/sugar/index.html&quot;&gt;Sugar ORM&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Insanely easy way to work with Android Databases. - Sugar ORM&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here are &lt;a href=&quot;http://developer.android.com/guide/topics/data/data-storage.html&quot;&gt;other storage options&lt;/a&gt; you could check out. Typically using &lt;a href=&quot;http://developer.android.com/training/basics/data-storage/databases.html&quot;&gt;SQLite in Android&lt;/a&gt; required a lot of boilerplate code, which took considerable time. But with Sugar ORM, all you need is a model (bean) class and you’re good to go. Taking the example of a note app similar to &lt;a href=&quot;http://www.google.co.in/keep/&quot;&gt;Google Keep&lt;/a&gt;, we’ll see how to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add a new note (save)&lt;/li&gt;
&lt;li&gt;Delete note&lt;/li&gt;
&lt;li&gt;Modify&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Setting up Sugar ORM&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Add this under your &lt;strong&gt;build.gradle&lt;/strong&gt; dependencies block:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;compile &apos;com.github.satyan:sugar:1.4&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;Modify your &lt;strong&gt;AndroidManifest.xml&lt;/strong&gt; as follows:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;
   …

    
    
    
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Designing Entities&lt;/h3&gt;
&lt;p&gt;A model (bean) class which extends &lt;strong&gt;SugarRecord&lt;/strong&gt; is all you need. Sugar ORM will use the information in this class to automatically create a table. Awesome right? Since ours is a note app, the entity will simple be &lt;strong&gt;Note&lt;/strong&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Note extends SugarRecord {

String title, note;
    long time;
    // Default constructor is important!
    public Note() {
    }

public Note(String title, String note, long time) {
        this.title = title;
        this.note = note;
        this.time = time;
    }
 …
// Getter setters here
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;The UI&lt;/h2&gt;
&lt;p&gt;For the scope of this tutorial, I will simple show you how my UI will look like. Let’s concentrate on how Sugar ORM works instead. There are just 2 screens:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-sqlite-database-tutorial-sugar-orm/sugar-orm-layout-list-notes-744x1303.png&quot; alt=&quot;sugar orm layout list notes&quot; title=&quot;MainActivity&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-sqlite-database-tutorial-sugar-orm/sugar-orm-layout-add-note-744x1303.png&quot; alt=&quot;sugar orm layout add note&quot; title=&quot;AddNoteActivity&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Nothing complex here. Those are simple list detail views. I made quick work of it with the Design Support Library. If you’re unfamiliar with that, then these tutorials can help. &lt;strong&gt;READ ALSO:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/toolbar-animation-with-android-design-support-library/&quot;&gt;Toolbar Animation (Flexible Space with Image Pattern)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/material-design-tabs-with-android-design-support-library/&quot;&gt;Material Design Tabs with Design Support Library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/easy-navigation-drawer-with-design-support-library/&quot;&gt;Easy Navigation Drawer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I setup a StaggeredGridLayout for my RecyclerView, akin to Google Keep.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;StaggeredGridLayoutManager gridLayoutManager =
        new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
gridLayoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);
recyclerView.setLayoutManager(gridLayoutManager);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now let’s move on to how we can easily perform basic database functions.&lt;/p&gt;
&lt;h2&gt;CRUD made easy with Sugar ORM&lt;/h2&gt;
&lt;h3&gt;Create&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;Note note = new Note(title, desc, time);
note.save();
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Update&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;Note note = Note.findById(Note.class, id);
note.title = “updated title here&quot;;
note.save();
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Delete&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;Note note = Note.findById(Note.class, id);
note.delete();
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Listing all notes&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;List notes = Note.listAll(Note.class);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let’s take a small breather here. Were we able to do CRUD operations, in just one line each? That’s amazing!&lt;/p&gt;
&lt;h2&gt;Queries&lt;/h2&gt;
&lt;p&gt;What is SQL if you can’t use queries? Sugar has got you covered there too! There are 2 ways to do this. Let’s take an example to compare the two.&lt;/p&gt;
&lt;h3&gt;Raw Query&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;List notes = Note.findWithQuery(Note.class, &quot;Select * from Note where name = ?&quot;, &quot;mynote&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Query Builder&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;Select.from(Note.class)
.where(Condition.prop(&quot;title&quot;).eq(&quot;mynote&quot;),
Condition.prop(&quot;description&quot;).eq(&quot;notedesc&quot;))
.list();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From this point on, I highly encourage you to build a simple notes app on your own. Use this post and the link to Sugar&apos;s docs for reference. However, if you think you need help, don&apos;t worry, read on below.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Sugar ORM in our Notes app&lt;/h2&gt;
&lt;p&gt;Now that we have the basics done, let&apos;s see how Sugar ORM can help us make a simple Notes app. With most of the boilerplate code out of the way, this should be a snap. We&apos;ve already seen how to add a note above. We do this in the &lt;strong&gt;AddNoteActivity.java&lt;/strong&gt; class. Pretty simple.&lt;/p&gt;
&lt;h3&gt;Updating Notes&lt;/h3&gt;
&lt;p&gt;We can use the same Activity to update the existing note. We do this by passing an Intent from &lt;strong&gt;MainActivity.java&lt;/strong&gt;. Here&apos;s the snippet:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;List notes = Note.find(Note.class, &quot;title = ?&quot;, title);
                 if (notes.size() &amp;gt; 0) {

                     Note note = notes.get(0);
                     note.title = newTitle;
                     note.note = newDesc;
                     note.time = newTime;

                     note.save();
                 }
              finish();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First fetch the Note from the database. I&apos;m finding it based on the title, but ideally you&apos;d do it using an ID of sorts. I simply update that note object with my new data and save, successfully updating it.&lt;/p&gt;
&lt;h3&gt;Making RecyclerView play nice with Sugar&lt;/h3&gt;
&lt;p&gt;Everything ultimately boils down to how your RecyclerView can display and update the notes. Make it play nice with the changes you do. Let&apos;s see how we can update our RecyclerView depending on changes such as deleting, adding and modifying a note. We initially display all notes saved via Sugar simply like this in your &lt;strong&gt;onCreate()&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; notes = Note.listAll(Note.class);

adapter = new NotesAdapter(MainActivity.this, notes);
recyclerView.setAdapter(adapter);
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Update RecylerView after creating a note&lt;/h4&gt;
&lt;p&gt;We return to &lt;strong&gt;MainActivit****y&lt;/strong&gt; using finish(), after creating a new note in &lt;strong&gt;AddNoteActivity&lt;/strong&gt;. So what get&apos;s triggered upon return? &lt;strong&gt;onResume()&lt;/strong&gt;. So this is where we refresh our RecyclerView.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;final long newCount = Note.count(Note.class);

    if (newCount &amp;gt; initialCount) {
        // A note is added

        // Just load the last added note (new)
        Note note = Note.last(Note.class);
        notes.add(note);
        adapter.notifyItemInserted((int) newCount);

        initialCount = newCount;
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since the newly created note would be the last item added, we simply fetch that and notify our adapter of the same.&lt;/p&gt;
&lt;h5&gt;Deleting a note&lt;/h5&gt;
&lt;p&gt;I&apos;m using Swipe to Dismiss to achieve this. Here&apos;s the logic:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;final int position = viewHolder.getAdapterPosition();
               final Note note = notes.get(viewHolder.getAdapterPosition());
               notes.remove(viewHolder.getAdapterPosition());
               adapter.notifyItemRemoved(position);

               note.delete();
               initialCount -= 1;

               Snackbar.make(recyclerView, &quot;Note deleted&quot;, Snackbar.LENGTH_SHORT)
                       .setAction(&quot;UNDO&quot;, new View.OnClickListener() {
                           @Override
                           public void onClick(View v) {

                               note.save();
                               notes.add(position, note);
                               adapter.notifyItemInserted(position);
                               initialCount += 1;

                           }
                       })
                       .show();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Observe that we take care of notifying our adapter here too, after an item is deleted via a swipe to dismiss. &lt;strong&gt;READ ALSO:&lt;/strong&gt; &lt;a href=&quot;https://blog.iamsuleiman.com/swipe-to-dismiss-recyclerview-itemtouchhelper/&quot;&gt;Swipe to Dismiss for RecyclerView with ItemTouchHelper&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Output&lt;/h2&gt;
&lt;p&gt;Now let&apos;s see Sugar work its magic. &lt;a href=&quot;https://youtu.be/_YMlz44yFkQ&quot;&gt;Watch on YouTube&lt;/a&gt; As you can see, Sugar ORM for Android really took away a lot of boilerplate code needed to start using SQLite in our apps. We took an example of a Note app as our use case, and this Android SQLite Database tutorial showed us how easy we can use databases thanks to Sugar ORM. As always, here&apos;s the source code link: &lt;a href=&quot;https://github.com/Suleiman19/Android-Note-app-with-Sugar-ORM/blob/master/app/src/main/java/com/grafixartist/noteapp/MainActivity.java&quot;&gt;GitHub&lt;/a&gt; What did you make with Sugar ORM? Drop &apos;em in the comments below, or subscribe for more tutorials like this!&lt;/p&gt;
</content:encoded></item><item><title>Swipe to Dismiss for RecyclerView with ItemTouchHelper</title><link>https://blog.iamsuleiman.com/swipe-to-dismiss-recyclerview-itemtouchhelper/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/swipe-to-dismiss-recyclerview-itemtouchhelper/</guid><description>A hidden gem in Android Support Library, is the built in Swipe to Dismiss functionality. Using the ItemTouchHelper(http://developer.android.com/refere</description><pubDate>Thu, 21 Jan 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A hidden gem in Android Support Library, is the built in Swipe to Dismiss functionality. Using the &lt;a href=&quot;http://developer.android.com/reference/android/support/v7/widget/helper/ItemTouchHelper.html&quot;&gt;ItemTouchHelper&lt;/a&gt; class, we can add this to a RecyclerView.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a &lt;a href=&quot;http://developer.android.com/reference/android/support/v7/widget/helper/ItemTouchHelper.SimpleCallback.html&quot;&gt;SimpleCallback&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {

        @Override
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
            return false;
        }

        @Override
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
            //Remove swiped item from list and notify the RecyclerView
        }
    };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;strong&gt;onSwiped()&lt;/strong&gt; method is where you should remove the item. Don&apos;t forget to notify your RecyclerView! 2. Finally, create an ItemTouchHelper instance and attach it to RecyclerView.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleCallback);
itemTouchHelper.attachToRecyclerView(recyclerView);
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Onboarding with Android ViewPager: The Google Way</title><link>https://blog.iamsuleiman.com/onboarding-android-viewpager-google-way/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/onboarding-android-viewpager-google-way/</guid><description>In this tutorial, learn to create an onboarding experience for your apps with Android ViewPager. Similar to the product tour app intro in Google Drive</description><pubDate>Wed, 16 Dec 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In this tutorial, learn to create an onboarding experience for your apps with Android ViewPager. Similar to the product tour app intro in Google Drive app. When you launch an app for the first time, you see the onboarding experience. It displays slides, highlighting features about the app with vibrant imagery. Let&apos;s make one for our app, the way Google does for theirs.&lt;/p&gt;
&lt;h2&gt;The &apos;Onboarding Experience&apos;&lt;/h2&gt;
&lt;p&gt;Its also known as &lt;em&gt;App Intro&lt;/em&gt; or &lt;em&gt;Product Tour&lt;/em&gt;. Call it what you want, but its what every user sees when opening a new app. Also, every other app includes it. Google too. This type of Onboarding is known as &lt;a href=&quot;https://material.google.com/growth-communications/onboarding.html#onboarding-onboarding-models&quot;&gt;&lt;strong&gt;Top User Benefits&lt;/strong&gt;&lt;/a&gt; model, as noted in the Material Design spec.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Display a brief autoplay carousel (or animatic) highlighting up to three benefits of using the app. - &lt;a href=&quot;http://material.google.com&quot;&gt;material.google.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;When to use it?&lt;/h3&gt;
&lt;p&gt;According to specs, use it when your app uses new features or major changes. DO NOT use it to highlight common features your users expect your app to have. In short, avoid anything that is trivial. Because its is called &apos;&lt;em&gt;Top&lt;/em&gt; User Benefits&apos; for a reason ;)&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;We will replicate the &lt;em&gt;Product Tour&lt;/em&gt; seen on the Google Drive Android App.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/onboarding-android-viewpager-google-way/google-drive-product-tour.gif&quot; alt=&quot;google drive product tour&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Upon first look, it may appear the background transitions color when the slide changes. But look closer and you&apos;ll will notice the drag changes color. In this tutorial we will:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;create an onboarding experience for our app with &lt;a href=&quot;http://developer.android.com/training/animation/screen-slide.html&quot;&gt;ViewPager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;control color transition while swiping&lt;/li&gt;
&lt;li&gt;display these slides when launching app for the first time&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;Add the support libraries to your &lt;strong&gt;build.gradle&lt;/strong&gt; file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dependencies {
    compile &apos;com.android.support:appcompat-v7:23.1.1&apos;
    compile &apos;com.android.support:design:23.1.1&apos;
    ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here&apos;s what I&apos;m using:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Android Studio 1.5.1&lt;/li&gt;
&lt;li&gt;Build Tools v23.0.2&lt;/li&gt;
&lt;li&gt;Support Libraries v23.1.1&lt;/li&gt;
&lt;li&gt;Gradle 1.5.0&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&apos;s use the updated App templates provided by Android Studio, to jumpstart this tutorial. Right click your package &amp;gt; New &amp;gt; Activity &amp;gt; &lt;strong&gt;Tabbed Activity&lt;/strong&gt;. Then, set the Navigation Style to &lt;strong&gt;Swipe Views (ViewPager)&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./onboarding-android-viewpager-google-way/android-studio-1.5.1-tabbed-activity-template-744x441.png&quot; alt=&quot;android studio 1.5.1 tabbed activity template&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;READ ALSO:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/image-gallery-app-android-studio-1-4-glide/&quot;&gt;Create an Image Gallery App with Android Studio 1.4 and Glide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/using-vector-assets-for-icons-in-android-studio-1-4/&quot;&gt;Using Vector Assets for Icons in Android Studio 1.4&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Tabbed Activity Template&lt;/h3&gt;
&lt;p&gt;I must say, this template did half the setup work for us. Brilliant! First, lets see what we have:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Our Activity (I called it &lt;strong&gt;PagerActivity&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SectionsPagerAdapter&lt;/strong&gt; (&lt;code&gt;ViewPager&lt;/code&gt; Adapter. Handles the slides)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PlaceholderFragment&lt;/strong&gt; (responsible for each slide&apos;s layout)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So with all this in place, let&apos;s tweak it to our needs. Open your &lt;code&gt;Activity&lt;/code&gt; &lt;strong&gt;layout.xml&lt;/strong&gt; and do the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Remove the &lt;code&gt;Toolbar&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add the button bar (which controls the ViewPager)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The button bar is what you noticed below the onboarding screen.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./onboarding-android-viewpager-google-way/button-bar-744x342.png&quot; alt=&quot;button bar&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;Layout:&lt;/h4&gt;
&lt;h5&gt;Button Bar&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;Skip Button&lt;/li&gt;
&lt;li&gt;Circle pager indicator (we&apos;re rolling our own here)&lt;/li&gt;
&lt;li&gt;Next/ Finish Button&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I wrapped all of this within a &lt;code&gt;FrameLayout&lt;/code&gt; and added it to my &lt;code&gt;Activity&lt;/code&gt; layout XML.&lt;/p&gt;
&lt;h5&gt;Fragment&lt;/h5&gt;
&lt;p&gt;Here&apos;s the layout breakdown for the &lt;code&gt;ViewPager&lt;/code&gt; &lt;code&gt;Fragment&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./onboarding-android-viewpager-google-way/onboarding-viewpager-layout-fragment-744x1303.jpg&quot; alt=&quot;onboarding viewpager layout-fragment&quot; /&gt;&lt;/p&gt;
&lt;p&gt;With the layout in place, lets get the onboarding to work with the &lt;code&gt;ViewPager&lt;/code&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Controlling color with ViewPager&lt;/h3&gt;
&lt;p&gt;The pager adapter is already tied to the ViewPager, so thats one less to worry about. As we swipe through, the color updates itself. In other words, the distance offset by the swipe determines the amount of color to change. We will have 3 simple slides, with a set color for each.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int color1 = ContextCompat.getColor(this, R.color.cyan);
int color2 = ContextCompat.getColor(this, R.color.orange); 
int color3 = ContextCompat.getColor(this, R.color.green); 

int[] colorList = new int[]{color1, color2, color3};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can detect changes to the ViewPager using the &lt;code&gt;OnPageChangeListener&lt;/code&gt;; the meat of this tutorial.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
     @Override
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
         
         /*
         color update
          */
         int colorUpdate = (Integer) evaluator.evaluate(positionOffset, colorList[position], colorList[position == 2 ? position : position + 1]);
         mViewPager.setBackgroundColor(colorUpdate);         
     }

     @Override
     public void onPageSelected(int position) {

         page = position;
         updateIndicators(page);

         switch (position) {
             case 0:
                 mViewPager.setBackgroundColor(color1);
                 break;
             case 1:
                 mViewPager.setBackgroundColor(color2);
                 break;
             case 2:
                 mViewPager.setBackgroundColor(color3);
                 break;
         }

         mNextBtn.setVisibility(position == 2 ? View.GONE : View.VISIBLE);
         mFinishBtn.setVisibility(position == 2 ? View.VISIBLE : View.GONE)
     }

     @Override
     public void onPageScrollStateChanged(int state) {

     }
 });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&apos;ve created a &lt;code&gt;ArgbEvaluator&lt;/code&gt; object to update the color. The transition happens from the previous slide&apos;s color, to the next slide&apos;s color. The &lt;code&gt;updateIndicators()&lt;/code&gt; method as you guessed, updates the pager indicators by toggling two drawables.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;void updateIndicators(int position) {
      for (int i = 0; i &amp;lt; indicators.length; i++) {
          indicators[i].setBackgroundResource(
                  i == position ? R.drawable.indicator_selected : R.drawable.indicator_unselected
          );
      }
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; &lt;code&gt;colorList[position == 2 ? position : position + 1]&lt;/code&gt; indicates that if the position is at the last slide, don&apos;t increment. Array size basics (goes from zero to (n-1). Otherwise this gives us an &lt;strong&gt;ArrayIndexOutOfBoundsException&lt;/strong&gt;. The &lt;strong&gt;page&lt;/strong&gt; variable helps track the ViewPager&apos;s current page position. Remember to increment this in your Next button&apos;s click listener! &lt;code&gt;onPageSelected()&lt;/code&gt; method is where we handle setting the background color for each slide. Finally check if we&apos;re on the last slide and make the finish button visible.&lt;/p&gt;
&lt;h4&gt;Updating the Indicators&lt;/h4&gt;
&lt;p&gt;I toggle between two simple drawables for the pager indicators. &lt;strong&gt;indicator_selected.xml&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;indicator_unselected.xml&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Calling it in&lt;/h2&gt;
&lt;p&gt;The onboarding screen is best called when the app is launched for the first time. This helps in making the user aware of what this app has to offer. However, from the second launch onwards, the app loads the home screen. We can achieve the same via a simple boolean &lt;code&gt;SharedPreference&lt;/code&gt;. Alternatively, if your app introduces major changes in an update, highlighting them with onboarding screens is a good approach. Here are 2 handy utility methods for reading and saving a SharedPreference:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static String readSharedSetting(Context ctx, String settingName, String defaultValue) {
      SharedPreferences sharedPref = ctx.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE);
      return sharedPref.getString(settingName, defaultValue);
  }

  public static void saveSharedSetting(Context ctx, String settingName, String settingValue) {
      SharedPreferences sharedPref = ctx.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE);
      SharedPreferences.Editor editor = sharedPref.edit();
      editor.putString(settingName, settingValue);
      editor.apply();
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Trigger first time launch&lt;/h3&gt;
&lt;p&gt;Check the &lt;code&gt;SharedPreference&lt;/code&gt; before you set your &lt;code&gt;Activity&lt;/code&gt;&apos;s layout. Then launch the onboarding if needed.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;isUserFirstTime = Boolean.valueOf(Utils.readSharedSetting(MainActivity.this, PREF_USER_FIRST_TIME, &quot;true&quot;));

       Intent introIntent = new Intent(MainActivity.this, PagerActivity.class);
       introIntent.putExtra(PREF_USER_FIRST_TIME, isUserFirstTime);

       if (isUserFirstTime) 
           startActivity(introIntent);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, to make the app know the onboarding is complete, we update this preference to false. Do this in your Finish button&apos;s click listener (The one we make visible on the last slide!).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mFinishBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            finish();
            //  update 1st time pref
            Utils.saveSharedSetting(PagerActivity.this, MainActivity.PREF_USER_FIRST_TIME, &quot;false&quot;);

        }
    });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;APP INTRO LIBRARY:&lt;/strong&gt; If you want a more simpler solution, or don&apos;t want deal with all this yourself, here&apos;s a &lt;a href=&quot;https://github.com/PaoloRotolo/AppIntro&quot;&gt;library alternative&lt;/a&gt; by Paolo Rotolo. &lt;strong&gt;KOTLIN ALTERNATIVE:&lt;/strong&gt; For all the Kotlin lovers out there, here&apos;s a &lt;a href=&quot;https://github.com/edsilfer/android-user-onboarding&quot;&gt;library by Edgar Fernandes&lt;/a&gt; based on this post. &lt;strong&gt;Taking it Further&lt;/strong&gt; If you&apos;re not satisfied with such a &apos;simplistic&apos; implementation. Or if you want to take it to the next level. Say with added animations and &lt;a href=&quot;http://developer.android.com/training/animation/screen-slide.html#pagetransformer&quot;&gt;PageTransformers&lt;/a&gt;, there&apos;s a &lt;a href=&quot;https://medium.com/android-news/creating-an-intro-screen-for-your-app-using-viewpager-pagetransformer-9950517ea04f#.ej1dvyroc&quot;&gt;brilliant post on Medium by Michell Bak&lt;/a&gt; that will help.&lt;/p&gt;
&lt;h2&gt;Final Output&lt;/h2&gt;
&lt;p&gt;Phew! That was quite some work. But hey, the new &lt;code&gt;Activity&lt;/code&gt; templates in Android Studio took care of half the work, didn&apos;t it? We just modified the layout to our liking and made the &lt;code&gt;ViewPager&lt;/code&gt; do a nice color transition. Here&apos;s the result: &lt;a href=&quot;https://youtu.be/gNCR1egddVI&quot;&gt;Watch on YouTube&lt;/a&gt; &lt;strong&gt;READ ALSO&lt;/strong&gt;:  &lt;a href=&quot;https://blog.iamsuleiman.com/overlap-a-transparent-status-bar/&quot;&gt;How to make the Status Bar transparent&lt;/a&gt; &lt;strong&gt;SOURCE CODE:&lt;/strong&gt; &lt;a href=&quot;https://github.com/Suleiman19/Android-Material-Design-for-pre-Lollipop/blob/master/MaterialSample/app/src/main/java/com/suleiman/material/activities/PagerActivity.java&quot;&gt;GitHub&lt;/a&gt;. That&apos;s a wrap for this post. We created a nice onboarding experience for our app&apos;s first time users. Used the ViewPager&apos;s scroll listeners to create a nice color transition on swipe. We even used a little SharedPreferences to display this screen for the first launch. My &apos;images&apos; don&apos;t quite match with the ones you see on the Drive app. But I&apos;m sure you can come up with something better! Drop &apos;em in the comments below.&lt;/p&gt;
</content:encoded></item><item><title>Runtime Permissions - Android Marshmallow Tutorial</title><link>https://blog.iamsuleiman.com/runtime-permissions-android-marshmallow/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/runtime-permissions-android-marshmallow/</guid><description>Runtime Permissions is a new permission model introduced in Android Marshmallow 6.0. Users are able to grant permissions during the app&apos;s runtime, rat</description><pubDate>Thu, 26 Nov 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Runtime Permissions is a new permission model introduced in Android Marshmallow 6.0. Users are able to grant permissions during the app&apos;s runtime, rather than during app install. Let&apos;s look at leveraging the new runtime permissions for Android Marshmallow.&lt;/p&gt;
&lt;h2&gt;The Runtime Permission Model&lt;/h2&gt;
&lt;p&gt;As always, lets first see what good it does. The &lt;a href=&quot;http://android-developers.blogspot.in/2015/08/building-better-apps-with-runtime.html&quot;&gt;new permission model&lt;/a&gt; allows users to take control of permissions and decide what to grant when. This can be controlled from the App Info &amp;gt; App permissions section.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./runtime-permissions-android-marshmallow/runtime-permissions-list.png&quot; alt=&quot;runtime-permissions-list&quot; title=&quot;App permissions list&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Good for users, not for developers&lt;/h3&gt;
&lt;p&gt;In pre Marshmallow, all permissions had to be granted during install time. An app at any point of time had access to ALL permissions it requested. The user had no choice but to accept them. But that has changed now. Runtime permissions give users control over the sensitive information they provide. They chose which apps can access what, and when they cannot. While this is good news for users, for a developer, it is not. Earlier we simply declared permissions in AndroidManifest.xml and we were on our way. But now apart from that, we need to check every time for a permission related task. Such as requesting the camera, calendar, contacts and so on. In addition, if the user denies the request permission, we need to handle that too. Phew! That&apos;s a lot of checking. You may wonder, &quot;If I&apos;m using the new permission model, what about pre Marshmallow devices?&quot;. Thankfully, implementing this gracefully falls back to the previous permission model on older devices. Great! That&apos;s one less to worry about.&lt;/p&gt;
&lt;h4&gt;Guidelines&lt;/h4&gt;
&lt;p&gt;Runtime permissions add a new dimension to your app&apos;s user experience. As an Android developer, you need to know WHEN and HOW to ask users for one, without annoying them. &lt;a href=&quot;https://www.google.com/design/spec/patterns/permissions.html?&quot;&gt;Design patterns for runtime permissions&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;If there&apos;s one way to lessen our worries, its using a library. Like &lt;a href=&quot;https://github.com/k0shk0sh/PermissionHelper&quot;&gt;this one&lt;/a&gt;. The Permission Helper library will help us implement runtime permissions a whole lot easier! Start by adding the library to your apps&apos; &lt;strong&gt;build.gradle&lt;/strong&gt; file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;compile &apos;com.github.k0shk0sh:PermissionHelper:1.0.7&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Normal and Dangerous Permissions&lt;/h3&gt;
&lt;p&gt;That&apos;s how Android&apos;s permissions are categorized into two groups. The full list is &lt;a href=&quot;https://developer.android.com/guide/topics/security/permissions.html#normal-dangerous&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;_C_over areas where your app needs to access data or resources outside the app&apos;s sandbox, but where there&apos;s very little risk to the user&apos;s privacy  - &lt;strong&gt;Normal Permissions&lt;/strong&gt; Dangerous permissions cover areas where the app wants data or resources that involve the user&apos;s private information - &lt;strong&gt;Dangerous Permissions&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Android will automatically grant access for Normal Permissions. So runtime permissions really come into play for the Dangerous Permissions.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Requesting Runtime Permissions&lt;/h2&gt;
&lt;p&gt;I&apos;m going to request the &apos;dangerous&apos; permission of reading the calendar. So for reference sake, I declare it like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;final String PERMISSION = Manifest.permission.READ_CALENDAR;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s bring the library&apos;s magic into play. Implement &lt;strong&gt;OnPermissionCallback&lt;/strong&gt; in your Activity. You&apos;ll get the following methods:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;onPermissionGranted()&lt;/strong&gt; - permission requested, and successfully granted by user&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;onPermissionDeclined()&lt;/strong&gt; - permission requested, but declined by user&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;onPermissionPreGranted()&lt;/strong&gt; - requested permission is already granted (allowed via app permissions screen)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;onPermissionNeedExplanation()&lt;/strong&gt; - requested permission was denied, tell the user why you need it&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;onPermissionReallyDeclined()&lt;/strong&gt; - requested permission was denied, and future requests were denied too. ( Can only be allowed from Settings now)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;onNoPermissionNeeded()&lt;/strong&gt; - fallback method for pre Marshmallow devices (older permissions model)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Firstly, initialize your PermissionsHelper:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;permissionHelper = PermissionHelper.getInstance(this);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then request your permission, say in your button&apos;s OnClickListener.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;permissionHelper.setForceAccepting(false).request(PERMISSION);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;setForceAccepting()&lt;/strong&gt; helps ensure that the request doesn&apos;t force the user to grant permission. Next, override the Activity&apos;s &lt;strong&gt;onRequestPermissionsResult()&lt;/strong&gt; method.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override
   public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
       permissionHelper.onRequestPermissionsResult(requestCode, permissions, grantResults);

   }
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Handling Requested Permission&lt;/h2&gt;
&lt;p&gt;After requesting the permission, we need to handle:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Permission grant&lt;/li&gt;
&lt;li&gt;Permission denial&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;./runtime-permissions-android-marshmallow/runtime-permissions-user-flow-744x415.png&quot; alt=&quot;runtime permissions user flow&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;1. Permission Grant&lt;/h3&gt;
&lt;p&gt;Override the Activity&apos;s &lt;strong&gt;onRequestPermissionsResult()&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

        permissionHelper.onRequestPermissionsResult(requestCode, permissions, grantResults);

    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the user granted permission, then &lt;strong&gt;onPermissionGranted&lt;/strong&gt;**()** is used, otherwise &lt;strong&gt;onPermissionDeclined()&lt;/strong&gt; is called. In the user flow diagram, you can see that a denied permission can be requested again. If requested again, this time a system dialog doesn&apos;t appear. But the permission will be added to your app&apos;s Permissions screen, from where you can manually enable disable requested permissions.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./runtime-permissions-android-marshmallow/runtime-permissions-system-dialo.png&quot; alt=&quot;runtime permissions system dialo&quot; title=&quot;System dialog shown first time&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./runtime-permissions-android-marshmallow/system-dialog-with-checkbox.png&quot; alt=&quot;system dialog with checkbox&quot; title=&quot;System dialog after first time&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So if you want to request a denied permission, use the &lt;strong&gt;onPermissionNeedExplanation()&lt;/strong&gt; method. Use this to tell the user WHY you need that permission. I do it with a simple dialog explaining why.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;AlertDialog dialog = new AlertDialog.Builder(this)
          .setTitle(title)
          .setMessage(message)
          .setPositiveButton(&quot;Request&quot;, new DialogInterface.OnClickListener() {
              @Override
              public void onClick(DialogInterface dialog, int which) {

                  permissionHelper.requestAfterExplanation(permission);

              }
          })
          .create();

  dialog.show();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, if you&apos;re requesting for a permission that is already granted, then the &lt;strong&gt;onPermissionPreGranted()&lt;/strong&gt; method comes really handy.&lt;/p&gt;
&lt;h3&gt;2. Permission Denial&lt;/h3&gt;
&lt;p&gt;Now what if the user denied permission? You need to handle that too. Since I&apos;m requesting to read the calendar, if the user refuses to grant my request, I need a contingency plan. You can handle denial with the &lt;strong&gt;onPermissionDeclined()&lt;/strong&gt; method. See the system dialog above, on the right? If the user checks &apos;&lt;em&gt;Never ask again&lt;/em&gt;&apos;, then that permission can ONLY be enabled via the app&apos;s permissions screen found here:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./runtime-permissions-android-marshmallow/app-info-settings.png&quot; alt=&quot;app-info-settings&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./runtime-permissions-android-marshmallow/runtime-permissions-list.png&quot; alt=&quot;runtime-permissions-list&quot; /&gt;&lt;/p&gt;
&lt;p&gt;You can handle this condition using the &lt;strong&gt;onPermissionReallyDeclined()&lt;/strong&gt; method.&lt;/p&gt;
&lt;h2&gt;Fallback&lt;/h2&gt;
&lt;p&gt;Like I mentioned earlier. Devices running pre Marshmallow reverts to using the older permission model. This is automatically managed, since permissions are defined in &lt;strong&gt;AndroidManifest.xml&lt;/strong&gt;. One less worry for us. Cheers!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Final Output&lt;/h2&gt;
&lt;p&gt;With everything in it&apos;s place, let&apos;s finally run our app and watch Runtime Permissions in action! In my demo, I&apos;ve printed logs to a TextView. This way, you can see which methods are called when. &lt;a href=&quot;https://youtu.be/UkGj3Obk2DA&quot;&gt;Watch on YouTube&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Source code on &lt;a href=&quot;https://github.com/Suleiman19/Marshmallow-Sample/blob/master/app/src/main/java/com/grafixartist/marshmallowsample/PermissionActivity.java&quot;&gt;GitHub&lt;/a&gt;.&lt;/h3&gt;
&lt;p&gt;That&apos;s all for this post. I hope runtime permissions with Android Marshmallow is clear now. Especially thanks to the Permission Helper library. If this post helped you handle runtime permissions like a pro, considering sharing so others can benefit too. Cheers!&lt;/p&gt;
</content:encoded></item><item><title>Google Chrome Custom Tabs Android Tutorial</title><link>https://blog.iamsuleiman.com/google-chrome-custom-tabs-android-tutorial/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/google-chrome-custom-tabs-android-tutorial/</guid><description>Android Marshmallow introduced Chrome Custom Tabs. This allows us to load Web URLs natively from within our app. It leads to a more faster experience,</description><pubDate>Mon, 16 Nov 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Android Marshmallow introduced Chrome Custom Tabs. This allows us to load Web URLs natively from within our app. It leads to a more faster experience, with customizable options making Chrome Custom Tabs more akin to our app&apos;s branding. It&apos;s been a while since &lt;a href=&quot;http://android-developers.blogspot.in/2015/09/android-marshmallow-ready-for-devices.html&quot;&gt;Android Marshmallow&lt;/a&gt; is out, along with a slew of new features for both users and developers. I feel now&apos;s the right time to start updating our apps, so existing Android Marshmallow users can take advantage of what&apos;s in store.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/google-chrome-custom-tabs-android-tutorial/chrome-custom-tabs-speed.gif&quot; alt=&quot;chrome custom tabs speed&quot; title=&quot;Image Credit: Google&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Android Marshmallow &lt;a href=&quot;http://android-developers.blogspot.in/2015/09/chrome-custom-tabs-smooth-transition.html&quot;&gt;Chrome Custom Tabs&lt;/a&gt; are blazing fast! I mean just look at that speed. This is amazing progress. I remember how I dread clicking on an external link in Facebook, Twitter or Feedly. I used to cringe each time a Chrome browser opens slowly. You see, I’m no fan of mobile web browsing. But this will change that. Allowing UI customization and loading web content from WITHIN your app. This is something I’m looking forward to.&lt;/p&gt;
&lt;h2&gt;When to use it?&lt;/h2&gt;
&lt;p&gt;If your app redirects your users to third- party content, or URLs outside your domain, you need to use Chrome Custom Tabs. Here&apos;s why:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Native in-app loading experience&lt;/li&gt;
&lt;li&gt;Chrome Custom Tabs load nearly twice as fast as WebView&lt;/li&gt;
&lt;li&gt;Allows UI customization for Toolbar, bringing it closer to your branding&lt;/li&gt;
&lt;li&gt;&apos;Pre-warming&apos; of browser in the background, allows for faster load times&lt;/li&gt;
&lt;li&gt;Shared Cookie jar with Chrome&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Frankly I&apos;ve seen a couple of code samples, by Google and one on &lt;a href=&quot;http://Medium.com&quot;&gt;Medium.com&lt;/a&gt;, but those are fairly complex involving a lot of custom classes and helpers for the fallback. So I&apos;ve decided NOT to go that way. Instead I&apos;ll show you a simple, straightforward way to achieve this. Because for developers, using a new feature must ease a task, not add to our burden. So let&apos;s get started with the Custom Chrome Tabs Android Tutorial.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Chrome Custom Tabs Library&lt;/h2&gt;
&lt;p&gt;Start by adding this line to your &lt;strong&gt;build.gradle&lt;/strong&gt; file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dependencies {
    compile &apos;com.android.support:customtabs:23.1.0&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./google-chrome-custom-tabs-android-tutorial/Screen-Shot-2015-11-13-at-1.39.47-PM.png&quot; alt=&quot;android studio 1.4 blank activity template&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I&apos;m using Android Studio 1.4 and the updated &lt;strong&gt;Blank Activity&lt;/strong&gt; template. This gives me a layout complete with a FAB and content holder, without having me to worry about initial setup.  For my &lt;strong&gt;activity_main.xml&lt;/strong&gt;, I&apos;ve kept nothing but a  FAB, which upon click will load my web URL in a Chrome Custom Tab. Also Read:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/image-gallery-app-android-studio-1-4-glide/&quot;&gt;Create an Image Gallery App with Android Studio 1.4 &amp;amp; Glide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/using-vector-assets-for-icons-in-android-studio-1-4/&quot;&gt;Use Vector Assets for Icons in Android Studio 1.4&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Fallback? No problem!&lt;/h3&gt;
&lt;p&gt;You may wonder about a fallback from Chrome Custom Tabs to WebView? Incase the user doesn&apos;t have Chrome. Let me clear a few things here.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Chrome Custom Tabs works with Chrome 45 &amp;amp; above&lt;/li&gt;
&lt;li&gt;It is not exclusive to Android Marshmallow. (Just that it was introduced along with it!)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The good news is, we just need to worry about launching the Chrome Custom Tab. The support library takes care of the fallback for us. Which means, if the user doesn&apos;t have Chrome, it will load the same in a WebView. Neat!&lt;/p&gt;
&lt;h2&gt;Pre-Warming Chrome Custom Tab&lt;/h2&gt;
&lt;p&gt;I know Chrome Custom Tabs are fast. But when there&apos;s an option to make it faster, then why not? Pre-warming allows us to tell Chrome to warm up its browser, and initialize itself. We also tell it the URL which the user is likely to open. So since we&apos;ll do all this beforehand, when the user actually clicks a URL, launching Chrome Custom Tabs, they get a near instantaneous experience. Users hate to wait, so I strongly recommend you take advantage of pre-warming.&lt;/p&gt;
&lt;h3&gt;Custom Tabs Service Connection&lt;/h3&gt;
&lt;p&gt;To take advantage of pre-warming, we need to bind the &lt;strong&gt;CustomTabsService&lt;/strong&gt; and initialize the &lt;strong&gt;CustomtabsClient&lt;/strong&gt; in it&apos;s callback.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mCustomTabsServiceConnection = new CustomTabsServiceConnection() {
          @Override
          public void onCustomTabsServiceConnected(ComponentName componentName, CustomTabsClient customTabsClient) {

              //Pre-warming
              mClient = customTabsClient;
              mClient.warmup(0L);
              mCustomTabsSession = mClient.newSession(null);
          }

          @Override
          public void onServiceDisconnected(ComponentName name) {
              mClient = null;
          }
      };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After this, we bind the Service.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CustomTabsClient.bindCustomTabsService(MainActivity.this, CUSTOM_TAB_PACKAGE_NAME, mCustomTabsServiceConnection);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;CUSTOM_TAB_PACKAGE_NAME&lt;/strong&gt; is Chrome&apos;s package name. Which is &quot;&lt;strong&gt;com.android.chrome&lt;/strong&gt;&quot;. Note that in order to make pre-warming fully effective, make sure you to do this well in advance, giving considerable time between pre-warming and actually launching the URL.&lt;/p&gt;
&lt;h2&gt;Custom Tabs Intent Builder&lt;/h2&gt;
&lt;p&gt;With pre-warming done, next is to define a few launch options for Chrome Custom Tab. We do this using the &lt;strong&gt;CustomTabsIntent Builder&lt;/strong&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;customTabsIntent = new CustomTabsIntent.Builder(mCustomTabsSession)
              .setToolbarColor(ContextCompat.getColor(this, R.color.colorPrimary))
              .setShowTitle(true)
              .build();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are a lot of customization options available with the Builder. I suggest you take your time, and define what you need. I&apos;ve set the basics, my primary brand color and displayed the URL title. You can also define Chrome&apos;s enter and exit animations with &lt;strong&gt;setExitAnimations()&lt;/strong&gt; &amp;amp; &lt;strong&gt;setStartAnimations()&lt;/strong&gt; respectively. If you play around with the Builder, you will find options to set Action buttons, a Close button and even entire Menus. But let&apos;s keep it simple for now and process with the bare essentials.&lt;/p&gt;
&lt;h2&gt;Launching Chrome&lt;/h2&gt;
&lt;p&gt;Finally with every setup done, we&apos;re set to actually tell Chrome to load our URL. You can do so with this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;customTabsIntent.launchUrl(MainActivity.this, Uri.parse(URL));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Where URL is the String for any website. I&apos;ve set it to my blog of course &quot;&lt;strong&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/&quot;&gt;https://blog.iamsuleiman.com/&lt;/a&gt;&quot;&lt;/strong&gt;. Since I want my FAB to load Chrome Custom Tabs on click, I add the above line inside its onClick listener. As suggested earlier, I strongly suggest you pre-warm Chrome at the earliest to give it enough time to initialize. Given possible network slowdowns and other issues, it needs some time. That is all! Simply run your app and watch Chrome Custom Tabs in action! &lt;a href=&quot;https://youtu.be/S9zhBm6R3no&quot;&gt;Watch on YouTube&lt;/a&gt; My test device runs Android Lollipop 5.1.1. Alternatively, you can even try it on an emulator (which does not have Chrome). It will switch to a WebView! Thats how the support library handles the fallback in Chrome&apos;s absence. &lt;strong&gt;SOURCE CODE:&lt;/strong&gt; Available on &lt;a href=&quot;https://github.com/Suleiman19/Marshmallow-Sample/blob/master/app/src/main/java/com/grafixartist/marshmallowsample/CustomTabsActivity.java&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Barely Scratched the Surface&lt;/h2&gt;
&lt;p&gt;Chrome Custom Tabs is a brilliant addition to the Android arsenal. Handling third party URLs has been bugging us from a long time now! It&apos;s finally great to see an elegant solution to this. However, there is a LOT more flexibility which Chrome Custom Tabs allow. I&apos;ve only included essentials to get you started. Reducing the learning curve. But if you want to know everything that&apos;s under the hood, &lt;a href=&quot;https://developer.chrome.com/multidevice/android/customtabs&quot;&gt;developer.chrome.com&lt;/a&gt; has you covered for reference.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Hope the tutorial helped you implement Chrome Custom Tabs easily. If you liked it, do considering sharing &amp;amp; subscribing. Cheers!&lt;/p&gt;
</content:encoded></item><item><title>How to create an Image Gallery App with Glide - Android Tutorial</title><link>https://blog.iamsuleiman.com/image-gallery-app-android-studio-1-4-glide/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/image-gallery-app-android-studio-1-4-glide/</guid><description>Let’s look at how fast we can create a simple image gallery app in Android using Glide. An image loading and caching library which takes care of almos</description><pubDate>Mon, 26 Oct 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Let’s look at how fast we can create a simple image gallery app in Android using Glide. An image loading and caching library which takes care of almost everything for us.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Glide is a fast and efficient open source media management and image loading framework for Android that wraps media decoding, memory and disk caching, and resource pooling into a simple and easy to use interface.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We’ll be creating an image gallery app, pretty common for Android app development. We will use &lt;a href=&quot;https://github.com/bumptech/glide&quot;&gt;Glide&lt;/a&gt; to handle image loading and caching. Then load these images in fullscreen upon tap. This will use a ViewPager allowing us to swipe between images. After updating to &lt;a href=&quot;http://android-developers.blogspot.in/2015/09/android-studio-14.html&quot;&gt;Android Studio 1.4&lt;/a&gt;, I’m glad that they’ve updated the default app templates as well. We will be using this to make quick work of the app. Let’s get started.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./image-gallery-app-android-studio-1-4-glide/Screen-Shot-2015-10-23-at-10.48.03-PM.png&quot; alt=&quot;Android Studio 1.4 blank activity template&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Fire up Android Studio 1.4 and create a new app.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Minimum SDK: API 14 Android 4.0&lt;/li&gt;
&lt;li&gt;Choose the ‘Blank Activity’ template and next, hit Finish//img on the right&lt;/li&gt;
&lt;li&gt;Remove the Floating Action Button (FAB) from your layout and Activity&lt;/li&gt;
&lt;li&gt;Include Glide in your &lt;strong&gt;build.gradle&lt;/strong&gt; file:    &lt;code&gt;compile &apos;com.github.bumptech.glide:glide:3.6.1&apos;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add Android Support v4 library, since Glide depends on it&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; I&apos;m using grade version &lt;strong&gt;1.4.0-beta3&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;MainActivity&lt;/h2&gt;
&lt;p&gt;This simply consists of a RecyclerView, its adapter, item layout and its POJO model class.&lt;/p&gt;
&lt;h3&gt;Android Image Gallery Layout&lt;/h3&gt;
&lt;p&gt;As expected, Android Studio has already added a skeleton layout for us (courtesy of the Design Support Library). You should be pretty familiar with the Design Support library by now, so I’m just mentioning the layout skeleton here.&lt;/p&gt;
&lt;p&gt;If you don’t know what the Design Support library is, I strongly suggest you do. You can get started &lt;a href=&quot;https://blog.iamsuleiman.com/toolbar-animation-with-android-design-support-library/&quot;&gt;here&lt;/a&gt;. It covers the basics. While its not really required for this tutorial, you’d be surprised at how the library lets you create popular design patterns with ease.&lt;/p&gt;
&lt;h3&gt;Image Gallery Item Layout&lt;/h3&gt;
&lt;p&gt;This is the layout for EACH item the RecyclerView will hold. Since ours is an Android image gallery app, it will be a grid layout with each item being a square holding the image.&lt;/p&gt;
&lt;h3&gt;Layout Item Model&lt;/h3&gt;
&lt;p&gt;Being familiar with RecyclerViews should tell you that it needs an Adapter and a custom layout. Also to bridge the layout and its data we will create a model POJO class &lt;strong&gt;ImageModel&lt;/strong&gt;. This will contain getter setters for our data. For our image gallery app, just the image URL, and title will suffice.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class ImageModel {

    String name, url;

    public ImageModel() {
    }
    // Getters &amp;amp; Setters here
 
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;QUICK TIP:&lt;/strong&gt; To automatically generate getter setters, place your cursor on the variable you want to generate for. Hit &lt;strong&gt;Ctrl+Space&lt;/strong&gt;, from the Generate popup, select &lt;strong&gt;Getter and Setter&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;Layout Adapter&lt;/h3&gt;
&lt;p&gt;Adapter’s aren’t something that need a tutorial and I’m sure you’ve done this a hundred times yourselves, so go ahead and add that for me will ya? Here’s mine, just in incase ;-)&lt;/p&gt;
&lt;h4&gt;Using Glide to Load Images into Adapter&lt;/h4&gt;
&lt;p&gt;In the onBindViewHolder method is essentially where we ‘bind’ our data to each layout item, based on position. We’ll use Glide to load our images for us into the ImageView.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Glide.with(context).load(data.get(position).getUrl())
                   .thumbnail(0.5f)
                   .crossFade()
                   .diskCacheStrategy(DiskCacheStrategy.ALL)
                   .into(((MyItemHolder) holder).mImg);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Glide API, is seriously fun to use. It shares a striking resemblance to Picasso, so Picasso users will feel right at home with Glide. Every Glide call starts with the with() method providing a context.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;load() - provide the URL for Glide to load&lt;/li&gt;
&lt;li&gt;thumbnail() - provide the size multiplier for thumbnail size&lt;/li&gt;
&lt;li&gt;crossFade() - for a smoothly fading in the loading image into ImageView 4. diskCacheStrategy(ALL) - saves the source and result data (images) into cache. AKA faster loading, but larger cache. Alternatively use DiskCacheStrategy.RESULT 5. into(targetView) - this the layout ‘into’ which the image must be loaded.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Also, you can specify a placeholder and error layout for your ImageView with Glide, using the placeholder() and error() methods respectively.&lt;/p&gt;
&lt;h2&gt;Putting the Adapter Together&lt;/h2&gt;
&lt;p&gt;So far, you should have a RecyclerView, a RecyclerView adapter using the &lt;strong&gt;list_item.xml&lt;/strong&gt; and the list model POJO class. With all this in check, lets head over to &lt;strong&gt;MainActivity.java&lt;/strong&gt; and connect them together. &lt;strong&gt;NOTE:&lt;/strong&gt; For this tutorial, I’m storing 10 image URLs in an array. I&apos;m just going to use a regular boring Grid layout here. But if you&apos;re up for something more interesting like the StaggeredGridLayout (like in Pinterest), read &lt;a href=&quot;https://blog.iamsuleiman.com/pinterest-masonry-layout-staggered-grid/&quot;&gt;Create a Pinterest Style Masonry Layout&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class MainActivity extends AppCompatActivity {
…
ArrayList data = new ArrayList&amp;lt;&amp;gt;();
public static String IMGS[] = {
// Your image URLs here
};

@Override 
protected void onCreate(Bundle savedInstanceState) {
…
for (int i = 0; i &amp;lt; IMGS.length; i++) {
//	Adding images &amp;amp; title to POJO class and storing in Array (our data)
ImageModel imageModel = new ImageModel();
imageModel.setName(&quot;Image &quot; + i);
imageModel.setUrl(IMGS[i]);
data.add(imageModel);
}
…
mRecyclerView = (RecyclerView) findViewById(R.id.list);
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 3));
mRecyclerView.setHasFixedSize(true); // Helps improve performance

mAdapter = new GalleryAdapter(MainActivity.this, data);
mRecyclerView.setAdapter(mAdapter);
…
}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Go ahead, run your app now, you should get a nice grid getting populated with images loaded from the internet (courtesy of Glide). You can see how Glide loads in a low resolution image first and then transitions a higher quality one.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./image-gallery-app-android-studio-1-4-glide/android-studio-1.4-image-gallery-with-glide.png&quot; alt=&quot;android-studio-1.4-image-gallery-with-glide&quot; /&gt; *&lt;/p&gt;
&lt;p&gt;Give yourself a pat on the back for coming this far. Next, we’ll implement the Detail view; the fullscreen gallery complete with swiping between images.&lt;/p&gt;
&lt;h2&gt;Detail Activity&lt;/h2&gt;
&lt;p&gt;You needn’t alter anything in the DetailActivity’s layout so instead open your &lt;strong&gt;fragment_detail.xml&lt;/strong&gt; layout. Simply throw in an ImageView and we’re done.&lt;/p&gt;
&lt;h3&gt;Android Studio ViewPager Template&lt;/h3&gt;
&lt;p&gt;Again, Android Studio 1.4 makes this easy for us with a prebuilt template we can use. Right click package &amp;gt; New &amp;gt; Activity &amp;gt; Tabbed Activity. In the dialog, make sure Navigation Style is set to &lt;strong&gt;Swipe Views (ViewPager)&lt;/strong&gt;. My Activity name is &lt;strong&gt;DetailActivity&lt;/strong&gt;. Here’s the Activity structure for your reference:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class DetailActivity extends AppCompatActivity {
…
@Override 
protected void onCreate(Bundle savedInstanceState) {
…
}

/**
* A FragmentPagerAdapter that returns a fragment corresponding to 
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
…
}

/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
…
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_detail, container, false);
…
return rootView;
}
}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Frankly, 80% of the setup process is already done. You have a Fragment setup, the ViewPager and its adapter as well. Everything is defined. All you need to do is point your data to it.&lt;/p&gt;
&lt;h3&gt;Passing ArrayList Data between Activities&lt;/h3&gt;
&lt;p&gt;Yes we’re aware of passing data between Activities using Intents and Bundles. But what if we want to pass an ArrayList holding a custom object? Like in our case ArrayList ? Simple. Make the class imageModel implement &lt;strong&gt;Parcelable&lt;/strong&gt;. Now some of you may use Serializable, but &lt;a href=&quot;http://www.developerphil.com/parcelable-vs-serializable/&quot;&gt;here’s why its a bad idea&lt;/a&gt;. With this done, we can now pass this ArrayList via an Intent. So head back to MainActivity.java, add a click listener for your RecyclerView trigger the DetailActivity.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener(this,
        new RecyclerItemClickListener.OnItemClickListener() {

@Override 
public void onItemClick(View view, int position) {

Intent intent = new Intent(MainActivity.this, DetailActivity.class);
intent.putParcelableArrayListExtra(&quot;data&quot;, data);
intent.putExtra(&quot;pos&quot;, position);
startActivity(intent);

}
}));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I’ve declared my data variable like this: ArrayList data = new ArrayList&amp;lt;&amp;gt;(); &lt;strong&gt;NOTE:&lt;/strong&gt; If you’re having trouble rolling in your own click listener for RecyclerView. You can just use &lt;a href=&quot;https://github.com/Suleiman19/Gallery/blob/master/app/src/main/java/com/grafixartist/gallery/RecyclerItemClickListener.java&quot;&gt;this&lt;/a&gt; one instead as a more loosely coupled solution. Now you can retrieve your data in DetailActivity.java like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;data = getIntent().getParcelableArrayListExtra(&quot;data&quot;);
pos = getIntent().getIntExtra(&quot;pos&quot;, 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remember that in a typical gallery app, the Toolbar (ActionBar) will change name according to the image’s title. So upon launching this Activity, there must be an initial title. You can add one like this: setTitle(data.get(pos).getName()); Every time the ViewPager is swiped, the new image’s title must be updated. Do that using the ViewPager’s &lt;strong&gt;addOnPageChangeListener()&lt;/strong&gt; method.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
 	…
@Override 
public void onPageSelected(int position) {
setTitle(data.get(position).getName());
}
…
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Passing Data to ViewPager Adapter&lt;/h3&gt;
&lt;p&gt;This can simply be done by passing your ArrayList data as a parameter to the &lt;strong&gt;SectionsPageAdapter&lt;/strong&gt;. With this you can modify the adapter as such:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public SectionsPagerAdapter(FragmentManager fm, ArrayList data) {
    super(fm);
    this.data = data;
}

@Override 
public Fragment getItem(int position) {
return PlaceholderFragment.newInstance(position, data.get(position).getName(), data.get(position).getUrl());
}

@Override 
public int getCount() {
return data.size();
}

@Override 
public CharSequence getPageTitle(int position) {
return data.get(position).getName();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now for the last step. Fetching the information passed in the &lt;strong&gt;PlaceHolderFragment&lt;/strong&gt;’s newInstance() and using it to load the image in its layout.&lt;/p&gt;
&lt;h3&gt;Sending Data to Fragment using setArguments()&lt;/h3&gt;
&lt;p&gt;Android Studio gives me a warning saying passing data to Fragments via its constructor is a bad idea. So I’m going to trust that and use the &lt;strong&gt;setArguments()&lt;/strong&gt; method for the same.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override 
public void setArguments(Bundle args) {
    super.setArguments(args);
    this.pos = args.getInt(ARG_SECTION_NUMBER);
    this.name = args.getString(ARG_IMG_TITLE);
    this.url = args.getString(ARG_IMG_URL);
}

public static PlaceholderFragment newInstance(int sectionNumber, String name, String url) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
args.putString(ARG_IMG_TITLE, name);
args.putString(ARG_IMG_URL, url);
fragment.setArguments(args);
return fragment;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that the arguments passed in newInstance() is bundled and passed into the &lt;strong&gt;setArguments()&lt;/strong&gt; method. This is the way of passing data to Fragments. In the setArguments() method, we can retrieve that data and handle them. So lastly, all that’s left is to let Glide work its magic in our Fragment’s ImageView.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ImageView imageView = (ImageView) rootView.findViewById(R.id.detail_image);

Glide.with(getActivity()).load(url).into(imageView);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s a wrap! Run your app and take a look. Your grid should now detect taps and load into fullscreen. &lt;a href=&quot;https://youtu.be/_lxjfkYHdWg&quot;&gt;Watch on YouTube&lt;/a&gt; For this tutorial, we focused on creating a simple gallery. However, we haven&apos;t looked into things like image gestures such as zoom and pan. Also, it would be nice if there were screen transition animations. Yes, Material Design animations. Part 2 of the &lt;a href=&quot;https://blog.iamsuleiman.com/android-image-gallery-app-gestures-transition/&quot;&gt;image gallery tutorial covers transitions and gesture&lt;/a&gt;. No gallery app is without gestures, so it&apos;s definitely worth a read. &lt;strong&gt;Picasso VS Glide&lt;/strong&gt; Picasso and Glide are very similar in terms of API, but Glide wins hands down in terms of pure speed. But the downside is slightly reduced image quality. Glide also has GIF support, which is another win over Picasso. You can view their comparison breakdown &lt;a href=&quot;http://vardhan-justlikethat.blogspot.in/2014/09/android-image-loading-libraries-picasso.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;We&apos;ve seen how to rapidly create an Android image gallery app using Android Studio 1.4 Activity templates. Also handle images like a breeze using the Glide library. However I&apos;ve barely scratched the surface in terms of Glide&apos;s potential. So you can take a look at there full &lt;a href=&quot;https://github.com/bumptech/glide/wiki&quot;&gt;feature set here&lt;/a&gt;. &lt;a href=&quot;https://github.com/Suleiman19/Gallery&quot;&gt;GitHub (Source code)&lt;/a&gt; Hope this serves as a foundation for your Android gallery apps.&lt;/p&gt;
</content:encoded></item><item><title>Using Vector Assets for Icons in Android Studio 1.4</title><link>https://blog.iamsuleiman.com/using-vector-assets-for-icons-in-android-studio-1-4/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/using-vector-assets-for-icons-in-android-studio-1-4/</guid><description>Since Android Studio 1.4, we can use Vector Assets which was earlier restricted to Lollipop alone. This is more efficient since one drawable which req</description><pubDate>Tue, 06 Oct 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Since Android Studio 1.4, we can use Vector Assets which was earlier restricted to Lollipop alone. This is more efficient since one drawable which requires multiple instances saved in different density folders will now be replaced by just ONE single vector asset inside &lt;strong&gt;res/drawable/&lt;/strong&gt; You need to use Gradle 1.4 for this.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Add &lt;code&gt;&apos;com.android.tools.build:gradle:1.5.0&apos;&lt;/code&gt; to your &lt;strong&gt;build.gradle&lt;/strong&gt; file dependencies.&lt;/li&gt;
&lt;li&gt;Add a vector asset by right-clicking &lt;em&gt;res/drawable/ &amp;gt; New &amp;gt; Vector Asset&lt;/em&gt;. Android Studio provides a built-in viewer for you to pick your drawable.&lt;/li&gt;
&lt;li&gt;Reference your icon like you usually do. Eg: &lt;code&gt;android:icon=&quot;@drawable/ic_help_24dp&quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;NOTE:  Since the icons are black, you may want to tint your ActionBar icons white. You can do so by reference the icon like this: &lt;code&gt;menu.getItem(index).getIcon()&lt;/code&gt; and then &lt;a href=&quot;https://blog.iamsuleiman.com/tint-icons-in-android/&quot;&gt;use DrawableCompat to tint&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Parallax Scrolling Tabs with Android Design Support Library</title><link>https://blog.iamsuleiman.com/parallax-scrolling-tabs-design-support-library/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/parallax-scrolling-tabs-design-support-library/</guid><description>Material Design has seen the rise in on-scroll animations in Android apps. Certain designs include a parallax scroll effect with a header images, alon</description><pubDate>Tue, 15 Sep 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Material Design has seen the rise in on-scroll animations in Android apps. Certain designs include a parallax scroll effect with a header images, along with Tabs. In this post, we&apos;ll look at just that. Parallax scrolling is a popular pattern. Previously we&apos;ve seen such examples with the Flexible Space with Image and Quick Return pattern. In this post, we&apos;ll look at making parallax scrolling Tabs using Android Design Support Library. Parallax scrolling has been very popular in web design and now in app development as well. I&apos;ve seen quite a few people wanting to implement this and I wanted to provide a solution without using a third party library. So here it is. Creating Parallax Scrolling on Android is nothing but the &lt;strong&gt;Flexible Space with Image pattern&lt;/strong&gt;, with an added TabLayout.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./parallax-scrolling-tabs-design-support-library/parallax-scroll-header-tabs.png&quot; alt=&quot;parallax scroll header tabs&quot; title=&quot;Parallax scrolling Tabs with Header&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Parallax Scrolling Tabs in Android&lt;/h2&gt;
&lt;p&gt;Have you read the &lt;a href=&quot;https://blog.iamsuleiman.com/toolbar-animation-with-android-design-support-library/&quot;&gt;android tutorial for creating the Flexible Space with Image Pattern&lt;/a&gt;? If you have, then you would immediately recognise that all this needs is a TabLayout. For those who haven&apos;t read it, don&apos;t worry. I&apos;ll walk you through everything in this article. But wait, hold your horses! I just threw in the TabLayout and this is what I got.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./parallax-scrolling-tabs-design-support-library/parallax_tabs_toolbar_converge.png&quot; alt=&quot;&quot; title=&quot;Toolbar and Tabs overlap on collapse&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Unlike the typical &lt;a href=&quot;https://blog.iamsuleiman.com/material-design-tabs-with-android-design-support-library/&quot;&gt;Material Design Tabs&lt;/a&gt; attached to the &lt;code&gt;Toolbar&lt;/code&gt;, Tabs here are transparent. Here is the layout. So clearly, the plug and play doesn&apos;t work. It looks like some tweaks are required. So before I straight away paste the entire code here, let&apos;s look at the layout skeleton.&lt;/p&gt;
&lt;p&gt;&amp;lt;android.support.design.widget.CoordinatorLayout&amp;gt;
&amp;lt;android.support.design.widget.AppBarLayout&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  &amp;lt;android.support.design.widget.CollapsingToolbarLayout&amp;gt;
     &amp;lt;ImageView /&amp;gt;
     &amp;lt;android.support.v7.widget.Toolbar /&amp;gt;
     &amp;lt;android.support.design.widget.TabLayout /&amp;gt;
  &amp;lt;/android.support.design.widget.CollapsingToolbarLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/android.support.design.widget.AppBarLayout&amp;gt;
&amp;lt;/android.support.design.widget.CoordinatorLayout&amp;gt;&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;&lt;a href=&quot;https://developer.android.com/reference/android/support/design/widget/CollapsingToolbarLayout.html&quot;&gt;CollapsingToolbarLayout&lt;/a&gt;&lt;/strong&gt; is like a super FrameLayout. So take note of the ordering of elements inside. Whatever element you place last, is what appears on the top. This positioning is important to get the parallax scrolling to work. So now that you have an idea of the layout structure, behold the full XML layout code!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;android.support.design.widget.CoordinatorLayout
    xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    android:id=&quot;@+id/htab_maincontent&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    android:fitsSystemWindows=&quot;true&quot;&amp;gt;

    &amp;lt;android.support.design.widget.AppBarLayout
        android:id=&quot;@+id/htab_appbar&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:background=&quot;?attr/colorPrimary&quot;
        android:fitsSystemWindows=&quot;true&quot;
        android:theme=&quot;@style/ThemeOverlay.AppCompat.Dark.ActionBar&quot;&amp;gt;

        &amp;lt;android.support.design.widget.CollapsingToolbarLayout
            android:id=&quot;@+id/htab_collapse_toolbar&quot;
            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;256dp&quot;
            android:fitsSystemWindows=&quot;true&quot;
            app:contentScrim=&quot;?attr/colorPrimary&quot;
            app:layout_scrollFlags=&quot;scroll|exitUntilCollapsed|snap&quot;
            app:titleEnabled=&quot;false&quot;&amp;gt;

            &amp;lt;ImageView
                android:id=&quot;@+id/htab_header&quot;
                android:layout_width=&quot;match_parent&quot;
                android:layout_height=&quot;match_parent&quot;
                android:background=&quot;@drawable/header&quot;
                android:fitsSystemWindows=&quot;true&quot;
                android:scaleType=&quot;centerCrop&quot;
                app:layout_collapseMode=&quot;parallax&quot;/&amp;gt;

            &amp;lt;View
                android:layout_width=&quot;match_parent&quot;
                android:layout_height=&quot;match_parent&quot;
                android:alpha=&quot;0.3&quot;
                android:background=&quot;@android:color/black&quot;
                android:fitsSystemWindows=&quot;true&quot;/&amp;gt;

            &amp;lt;android.support.v7.widget.Toolbar
                android:id=&quot;@+id/htab_toolbar&quot;
                android:layout_width=&quot;match_parent&quot;
                android:layout_height=&quot;?attr/actionBarSize&quot;
                android:layout_gravity=&quot;top&quot;
                android:layout_marginBottom=&quot;48dp&quot;
                app:layout_collapseMode=&quot;pin&quot;
                app:popupTheme=&quot;@style/ThemeOverlay.AppCompat.Light&quot;/&amp;gt;

            &amp;lt;android.support.design.widget.TabLayout
                android:id=&quot;@+id/htab_tabs&quot;
                android:layout_width=&quot;match_parent&quot;
                android:layout_height=&quot;wrap_content&quot;
                android:layout_gravity=&quot;bottom&quot;
                app:tabIndicatorColor=&quot;@android:color/white&quot;
                app:tabSelectedTextColor=&quot;@android:color/white&quot;
                app:tabTextColor=&quot;@color/white_70&quot;/&amp;gt;

        &amp;lt;/android.support.design.widget.CollapsingToolbarLayout&amp;gt;

    &amp;lt;/android.support.design.widget.AppBarLayout&amp;gt;

    &amp;lt;android.support.v4.view.ViewPager
        android:id=&quot;@+id/htab_viewpager&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;match_parent&quot;
        app:layout_behavior=&quot;@string/appbar_scrolling_view_behavior&quot;/&amp;gt;

&amp;lt;/android.support.design.widget.CoordinatorLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Layout Breakdown&lt;/h3&gt;
&lt;p&gt;Some of the attributes here make the parallax scroll work. So let me walk you through them. &lt;strong&gt;21.&lt;/strong&gt; The total height that we want our collapsible header &lt;code&gt;View&lt;/code&gt; to have. &lt;strong&gt;25.&lt;/strong&gt; This is not the &lt;a href=&quot;https://blog.iamsuleiman.com/toolbar-animation-with-android-design-support-library/&quot;&gt;Flexible Space with Image pattern&lt;/a&gt;. We don&apos;t want the &lt;code&gt;Toolbar&lt;/code&gt; title to collapse. We want it fixed. So disable the title. &lt;strong&gt;34.&lt;/strong&gt; The flag that triggers the parallax effect upon scrolling. &lt;strong&gt;36 - 41&lt;/strong&gt; Scrim that makes Tab text more readable against the busy header background. &lt;strong&gt;47.&lt;/strong&gt; Remember that CollapsingToolbarLayout is an extension of &lt;code&gt;FrameLayout&lt;/code&gt;. So this attribute ensures the &lt;code&gt;Toolbar&lt;/code&gt; stays on top. &lt;strong&gt;48.&lt;/strong&gt; &lt;code&gt;TabLayout&lt;/code&gt; by default has a height of &lt;strong&gt;48dp&lt;/strong&gt;. Telling our &lt;code&gt;Toolbar&lt;/code&gt; to have a bottom margin of the same, avoids the overlap issue I showed you above. &lt;strong&gt;49.&lt;/strong&gt; Makes sure the &lt;code&gt;Toolbar&lt;/code&gt; consistently is pinned to the top. Otherwise when you start scrolling, the &lt;code&gt;Toolbar&lt;/code&gt; scrolls off screen. &lt;strong&gt;56.&lt;/strong&gt; Ensures the &lt;code&gt;TabLayout&lt;/code&gt; sticks to the bottom of the header.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./parallax-scrolling-tabs-design-support-library/layout-parallax-scrolling-breakdown.png&quot; alt=&quot;layout-parallax-scrolling-breakdown&quot; title=&quot;Breakdown of layout metrics&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;Setting up ViewPager in Activity.java&lt;/h4&gt;
&lt;p&gt;In case you forgot, the Tabs need a &lt;code&gt;ViewPager&lt;/code&gt; to work with, so let&apos;s take care of that in our &lt;strong&gt;Activity.java&lt;/strong&gt;. Let&apos;s start by creating a dummy &lt;code&gt;Fragment&lt;/code&gt;. For the sake of displaying some content, the &lt;code&gt;Fragment&lt;/code&gt; will display a &lt;code&gt;RecyclerView&lt;/code&gt;. Additionally, it&apos;s background color will change depending on it&apos;s position in the &lt;code&gt;ViewPager&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class DummyFragment extends Fragment {
     
      public DummyFragment() {
      }

      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
          View view = inflater.inflate(R.layout.dummy_fragment, container, false);
          ...
          RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.dummyfrag_scrollableview);

          LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity().getBaseContext());
          recyclerView.setLayoutManager(linearLayoutManager);

          SimpleRecyclerAdapter adapter = new SimpleRecyclerAdapter(list);
          recyclerView.setAdapter(adapter);
          ...
          return view;
      }
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that &lt;strong&gt;DummyFragment&lt;/strong&gt; is just a placeholder which I&apos;m using with a different background color for each of my Tabs. You on the other hand must define a Fragment accordingly for each of your Tabs.&lt;/p&gt;
&lt;h4&gt;ViewPager Adapter&lt;/h4&gt;
&lt;p&gt;A minimal Adapter for our ViewPager. (To hold 3 Fragments)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;static class ViewPagerAdapter extends FragmentPagerAdapter {
        private final List mmFragmentTitleList FragmentList = new ArrayList&amp;lt;&amp;gt;();
        private final List = new ArrayList&amp;lt;&amp;gt;();

        public ViewPagerAdapter(FragmentManager manager) {
            super(manager);
        }

        @Override
        public Fragment getItem(int position) {
            return mFragmentList.get(position);
        }

        @Override
        public int getCount() {
            return mFragmentList.size();
        }

        public void addFrag(Fragment fragment, String title) {
            mFragmentList.add(fragment);
            mFragmentTitleList.add(title);
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return mFragmentTitleList.get(position);
        }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;Hooking up ViewPager with TabLayout&lt;/h5&gt;
&lt;p&gt;Finally we&apos;ll attach the ViewPager to our TabLayout in the Activity&apos;s &lt;strong&gt;onCreate()&lt;/strong&gt; method.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;... 
TabLayout tabLayout = (TabLayout) findViewById(R.id.htab_tabs);
        tabLayout.setupWithViewPager(viewPager);

 tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {

                viewPager.setCurrentItem(tab.getPosition());

                switch (tab.getPosition()) {
                    case 0:
                        showToast(&quot;One&quot;);
                        break;
                    case 1:
                        showToast(&quot;Two&quot;);
                        ...
                  }
               }

  private void setupViewPager(ViewPager viewPager) {
        ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
        adapter.addFrag(new DummyFragment(getResources().getColor(R.color.accent_material_light)), &quot;CAT&quot;);
        adapter.addFrag(new DummyFragment(getResources().getColor(R.color.ripple_material_light)), &quot;DOG&quot;);
        adapter.addFrag(new DummyFragment(getResources().getColor(R.color.button_material_dark)), &quot;MOUSE&quot;);
        viewPager.setAdapter(adapter);
    }
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;strong&gt;setupViewPager()&lt;/strong&gt; method simply initializes my &lt;code&gt;Fragment&lt;/code&gt; and adds them to the &lt;code&gt;ViewPager&lt;/code&gt;. Nothing out of the ordinary here. The &lt;a href=&quot;https://blog.iamsuleiman.com/material-design-tabs-with-android-design-support-library/&quot;&gt;Material Design Tabs&lt;/a&gt; post does the same thing, which is why this has minimal explanation. However if you get stuck anywhere, below is a link to the source code (GitHub) which you can refer to :)&lt;/p&gt;
&lt;h6&gt;Dynamic Tab color with Palette API&lt;/h6&gt;
&lt;p&gt;The color you see the &lt;code&gt;Toolbar&lt;/code&gt; + &lt;code&gt;TabLayout&lt;/code&gt; take, is picked from the header image. Courtesy of the Palette API. Using this, we&apos;ll set colors for the &lt;code&gt;Toolbar&lt;/code&gt;, &lt;code&gt;TabLayout&lt;/code&gt; and Status Bar. This is easily done by the following code snippet:&lt;/p&gt;
&lt;p&gt;try {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.header);
Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
@SuppressWarnings(&quot;ResourceType&quot;)
@Override
public void onGenerated(Palette palette) {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;        int vibrantColor = palette.getVibrantColor(R.color.primary_500);
        int vibrantDarkColor = palette.getDarkVibrantColor(R.color.primary_700);
        collapsingToolbarLayout.setContentScrimColor(vibrantColor);
        collapsingToolbarLayout.setStatusBarScrimColor(vibrantDarkColor);
    }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;} catch (Exception e) {
// if Bitmap fetch fails, fallback to primary colors
Log.e(TAG, &quot;onCreate: failed to create bitmap from background&quot;, e.fillInStackTrace());
collapsingToolbarLayout.setContentScrimColor(
ContextCompat.getColor(this, R.color.primary_500)
);
collapsingToolbarLayout.setStatusBarScrimColor(
ContextCompat.getColor(this, R.color.primary_700)
);
}&lt;/p&gt;
&lt;p&gt;Notice that the actual Palette API calls reside in the try block. But it is good practice to always handle the fail case. Here, the Palette API can fail if we&apos;re unable to get a Bitmap. So as a fallback, we resort to using our app&apos;s primary colors.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Final Output&lt;/h2&gt;
&lt;p&gt;With everything in place, run your app and scroll down and watch that beautiful parallax scrolling.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/parallax-scrolling-tabs-design-support-library/parallax-scrolling-header-tab-op.gif&quot; alt=&quot;parallax scrolling header tab op&quot; title=&quot;Parallax scrolling Tabs output&quot; /&gt;&lt;/p&gt;
&lt;p&gt;We have a neat &lt;code&gt;TabLayout&lt;/code&gt; that plays nice with our &lt;code&gt;Toolbar&lt;/code&gt;. Our header image scrolls nicely and fades into our image&apos;s primary vibrant color. As you can see this is a neat pattern in use which many of you would have seen. A perfect use case for this would be in apps that have categories (sub divisions) like the Play Store app, and also require a neat header image (Master Detail being the perfect example). &lt;strong&gt;SOURCE CODE:&lt;/strong&gt; Find the source code for this project on &lt;a href=&quot;https://github.com/Suleiman19/Android-Material-Design-for-pre-Lollipop/blob/master/MaterialSample/app/src/main/java/com/suleiman/material/activities/TabsHeaderActivity.java&quot;&gt;GitHub&lt;/a&gt;. &lt;strong&gt;Alternate Library:&lt;/strong&gt; If you&apos;re not satisfied with the parallax scrolling the Design Support Library provides, or desire a greater degree of control and flexibility, you can use &lt;a href=&quot;https://github.com/florent37/MaterialViewPager&quot;&gt;MaterialViewPager by florent37&lt;/a&gt; on GitHub. Do share the post if you liked it! Cheers.&lt;/p&gt;
</content:encoded></item><item><title>Material Design for Tablets</title><link>https://blog.iamsuleiman.com/material-design-for-tablets/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/material-design-for-tablets/</guid><description>So far we&apos;ve seen use cases for popular design patterns restricted to a handset only. Now let&apos;s look at applying Material Design for Tablets in Androi</description><pubDate>Tue, 08 Sep 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;So far we&apos;ve seen use cases for popular design patterns restricted to a handset only. Now let&apos;s look at applying Material Design for Tablets in Android app development. New to Material Design? Get started with &lt;a href=&quot;https://blog.iamsuleiman.com/android-material-design-tutorial/&quot;&gt;Android Material Design for pre Lollipop&lt;/a&gt; first. Let&apos;s begin with the project setup so our app can handle different screen sizes, and fire up a layout accordingly. A fitting example to showcase the best tablet design would be the Navigation Drawer pattern. It&apos;s pretty famous and can be seen on almost any mobile app. On mobiles, you swipe right or tap the Hamburger menu to open it. While on tablet, it usually stays opened (Master Detail flow). Like a two pane layout. Let&apos;s look at making such a template for your tablet app.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./material-design-for-tablets/tablet-land-744x559.png&quot; alt=&quot;tablet-land&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Material Design Tablet Metrics&lt;/h2&gt;
&lt;p&gt;This doesn&apos;t involve you doing anything &apos;special&apos;. You just need to create appropriate folders for your tablet resources, and add relevant files. That is key.&lt;/p&gt;
&lt;h3&gt;Layout for Tablet Design&lt;/h3&gt;
&lt;p&gt;Here&apos;s the breakdown which shows the folders you need to have under &lt;strong&gt;res&lt;/strong&gt;/ folder. Keep in mind the default folder for layouts is &lt;strong&gt;res/layout&lt;/strong&gt; and for values its &lt;strong&gt;res/values&lt;/strong&gt;.  We&apos;re going to create alternate resources for tablets that will override these defaults. I&apos;ll try my best to keep it simple and not over-complicate.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./material-design-for-tablets/breakpoints-table-744x368.png&quot; alt=&quot;breakpoints-table&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The folders work on a concept of &lt;strong&gt;smallest width (sw&lt;/strong&gt;). The key takeaway here is that layouts above 600dp is tablet, with &lt;strong&gt;600dp&lt;/strong&gt; and &lt;strong&gt;720dp&lt;/strong&gt; being &lt;strong&gt;7 inch&lt;/strong&gt; and &lt;strong&gt;10 inch&lt;/strong&gt; tablets respectively. For alternative landscape configurations, append &lt;strong&gt;-land&lt;/strong&gt; to the folder name. For values folder it follows the same concept. This is the bare minimum and enough for most cases. However, if you&apos;re the curious one like me, here&apos;s the &lt;a href=&quot;https://www.google.co.in/design/spec/layout/adaptive-ui.html#adaptive-ui-breakpoints&quot;&gt;full breakdown&lt;/a&gt;.  I strongly suggest that you follow that link whenever making your folder structure for a hybrid tablet app. Simply because the Material Design specs are the updated guidelines and NOT &lt;a href=&quot;http://developer.android.com/guide/practices/screens_support.html&quot;&gt;this&lt;/a&gt;. So given that you&apos;ve understood everything that went on above, for this post, we need a layout for phone, and an alternate for tablet. Given that, we will need a &lt;strong&gt;res/layout&lt;/strong&gt; and &lt;strong&gt;res/layout-sw-600dp&lt;/strong&gt; folders. Tablets are best used in landscape so while you can go ahead and use the &lt;strong&gt;layout-sw-600dp&lt;/strong&gt; folder if you want, but the two pane layout is ideal for landscape, so I&apos;m going with the &lt;strong&gt;layout-sw-600dp-land&lt;/strong&gt; folder.&lt;/p&gt;
&lt;h3&gt;Dimensions&lt;/h3&gt;
&lt;p&gt;Also note that the dimension values that you specify, you must define its alternate dimension values in the &lt;strong&gt;res/values/dimens.xml&lt;/strong&gt; folder. Remember to use the correct &lt;strong&gt;values&lt;/strong&gt; folder for tablets. Example, the default activity margins are &lt;strong&gt;16dp&lt;/strong&gt; for mobile, and &lt;strong&gt;24dp&lt;/strong&gt; for 7 inch to 9 inch tablets. So I would define a dimension like this: PHONE: res/&lt;strong&gt;values&lt;/strong&gt;/dimens.xml: &lt;code&gt;&amp;lt;dimen name=&quot;activity_margin&quot;&amp;gt;16dp&amp;lt;/dimen&amp;gt;&lt;/code&gt; TABLET: res/&lt;strong&gt;values-sw600dp&lt;/strong&gt;/dimens.xml: &lt;code&gt;&amp;lt;dimen name=&quot;activity_margin&quot;&amp;gt;24dp&amp;lt;/dimen&amp;gt;&lt;/code&gt; Note how both dimension values have the same name, while residing in different &lt;strong&gt;res/values&lt;/strong&gt; folder. Android will take care of accessing the correct folder. In this case, it takes &lt;strong&gt;16dp&lt;/strong&gt; until a device&apos;s width is 599dp. Anything 600dp and beyond in width will take &lt;strong&gt;24dp&lt;/strong&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Enough of me rambling, let&apos;s dive into making our tablet app. Basically, we&apos;ll create 2 layouts, one for phone and another for tablet that reside in different layout folders. Then in our Activity class, we&apos;ll check which layout is in use and setup accordingly. Yep, it takes twice the effort my friend. That&apos;s why we use &lt;a href=&quot;http://developer.android.com/guide/components/fragments.html&quot;&gt;Fragments&lt;/a&gt; ;)&lt;/p&gt;
&lt;h2&gt;Phone Layout&lt;/h2&gt;
&lt;p&gt;Start by defining your res/&lt;strong&gt;layout&lt;/strong&gt;/activity_main.xml Since I mentioned we&apos;ll be doing a two pane layout, for phones that very layout is our regular Navigation Drawer. I&apos;m implementing a Material Navigation Drawer with the help of the &lt;a href=&quot;https://blog.iamsuleiman.com/toolbar-animation-with-android-design-support-library/&quot;&gt;Design Support Library&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To learn more about NavigationView or Navigation Drawer, read &lt;a href=&quot;https://blog.iamsuleiman.com/easy-navigation-drawer-with-design-support-library/&quot;&gt;Easy Navigation Drawer with Design Support Library&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Tablet Layout&lt;/h2&gt;
&lt;p&gt;Now for res/&lt;strong&gt;layout-sw600dp-land&lt;/strong&gt;/activity_main.xml Optionally, if you want the regular phone landscape to have this layout as well, then you can include this layout in res/&lt;strong&gt;layout-land&lt;/strong&gt;/ instead.&lt;/p&gt;
&lt;p&gt;The thing to notice here is, the &lt;strong&gt;ID&lt;/strong&gt; for NavigationView and FrameLayout (which inflates Fragment) are the same. The only thing different, is the Drawer layout in res/&lt;strong&gt;layout&lt;/strong&gt;/activity_main.xml. Hence we will use this difference to identify whether its a tablet or phone layout. Remember that the Android framework will automatically choose the correct layout. So we just need to check which one it is and react accordingly. This, we will handle in Java.&lt;/p&gt;
&lt;h2&gt;Handling Both Layouts in Activity&lt;/h2&gt;
&lt;p&gt;The crux of the Activity is this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  if (findViewById(R.id.drawer) != null) {
            mTwoPane = false;
            // Handle Phone layout setup here
        } else {
            mTwoPane = true;
            // Handle Tablet setup here
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We find any one ID that&apos;s unique to either layout (phone or tablet). Here, the Drawer exists only in for the phone layout, hence we check if a view containing that ID is inflated. So if the layout holding the Drawer is inflated, it means its a phone. Otherwise its tablet. We use this simple if condition to check the type of device and initialize accordingly, using a Boolean &apos;&lt;strong&gt;mTwoPane&lt;/strong&gt;&apos; to keep track of the changes. Alternatively you can fetch the device width and handle changes, but I find this solution more elegant.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class MainActivity extends AppCompatActivity {
    ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        setUpToolbar();

        if (findViewById(R.id.drawer) != null) {
//            Phone layout
            mTwoPane = false;

            setUpNavDrawer();
            ...
        } else {
//            Tablet layout
            mTwoPane = true;
            ...
            }
        }
        // Initialize &amp;amp; handle views here common to both Phone &amp;amp; Tablet
        mNavigationView = (NavigationView) findViewById(R.id.nav_view);
        // Inflate the common Fragment here @+id/main_content_area (FrameLayout)
        ...
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hope the comments are self explanatory. Anything specific to phone or tablet is handled in their respective if or else statements. What is common to both is handled outside them.&lt;/p&gt;
&lt;h2&gt;Final Output&lt;/h2&gt;
&lt;p&gt;Finally after a lot of folder creations and alternate resource files, we&apos;re ready to run our tablet app.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./material-design-for-tablets/Screenshot_2015-09-07-18-22-50.png&quot; alt=&quot;Screenshot_2015-09-07-18-22-50&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./material-design-for-tablets/Screenshot_2015-09-07-18-23-04-744x419.png&quot; alt=&quot;Screenshot_2015-09-07-18-23-04&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./material-design-for-tablets/tablet-portrait.png&quot; alt=&quot;tablet-portrait&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./material-design-for-tablets/tablet-land-744x559.png&quot; alt=&quot;tablet-land&quot; /&gt; *&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Source Code:&lt;/strong&gt; &lt;a href=&quot;https://github.com/Suleiman19/Material-Design-Tablet-App&quot;&gt;Available on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Wrap Up&lt;/h3&gt;
&lt;p&gt;I hope this post provided needed insights for you to get started on Material Design for Tablets. I&apos;ve used a pretty common use case- a two pane layout with the Navigation Drawer, covering small (600dp) and large (720dp) tablet versions. We&apos;ve seen how we can define alternate resource files in our folder structure which lets Android pick the right one depending on screen size. We also saw how to handle different layouts in our code and react accordingly. Designing for Android tablet opens up a whole new dimension for us designers to play more freely on a larger screen. Remember that a good app is one that intelligently makes use of available space, yet retaining familiarity. Hoping to see you come up with awesome layout designs. Do show them off in the comments below.&lt;/p&gt;
</content:encoded></item><item><title>Overlap a Transparent Status Bar</title><link>https://blog.iamsuleiman.com/overlap-a-transparent-status-bar/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/overlap-a-transparent-status-bar/</guid><description>There&apos;s a lot going on about making your Status Bar transparent for your Activities. But most of the time, its easier said than done and if android:fi</description><pubDate>Mon, 24 Aug 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;There&apos;s a lot going on about making your Status Bar transparent for your Activities. But most of the time, its easier said than done and if &lt;code&gt;android:fitsSystemWindows = &quot;true&quot;&lt;/code&gt; doesn&apos;t work for you, then there is another way. Add this before your &lt;code&gt;setContentView()&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  if (Build.VERSION.SDK_INT &amp;gt;= Build.VERSION_CODES.LOLLIPOP) {
            getWindow().getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
            getWindow().setStatusBarColor(getResources().getColor(R.color.black_trans80,null));

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remember that a transparent Status Bar works only on Lollipop and above. For Android KitKat 4.4 it is translucent. Android Jelly Bean 4.2 and below, it remains black and there&apos;s nothing you can do about that. The Status Bar color here could be anything, but as per norms it must be 20% opacity black. &lt;strong&gt;NOTE:&lt;/strong&gt; Don&apos;t forget to add a &lt;strong&gt;24dp&lt;/strong&gt; padding to your Toolbar top, since it will now be under the Status Bar.&lt;/p&gt;
</content:encoded></item><item><title>Create Gmail Style List in Android</title><link>https://blog.iamsuleiman.com/create-gmail-style-list-in-android/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/create-gmail-style-list-in-android/</guid><description>I&apos;m sure all of you would have noticed the list style in the Gmail app for Android. The placeholder for a person&apos;s photo is their first letter accente</description><pubDate>Thu, 13 Aug 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;m sure all of you would have noticed the list style in the Gmail app for Android. The placeholder for a person&apos;s photo is their first letter accented with a nice color. In fact even the stock Contacts app and the new Inbox by Gmail has a similar style.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./create-gmail-style-list-in-android/new-gmail-app-android-lollipop-100527807-primary.idge_-e1439471637849.jpg&quot; alt=&quot;new-gmail-app-android-lollipop-100527807-primary.idge&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Gmail&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/assets/images/create-gmail-style-list-in-android/Contact5-e1439471789505.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Lollipop Stock Contacts App&lt;/p&gt;
&lt;p&gt;This is a pretty neat way of handling the absence of a profile picture, instead of a mundane grey placeholder. This helps add more vibrancy to our app, giving it more &apos;pop&apos; and life. Let&apos;s look at how to make a Gmail style list using the &lt;a href=&quot;https://github.com/amulyakhare/TextDrawable&quot;&gt;TextDrawable&lt;/a&gt; library, as it makes it easy to mimic such a style. The reason for using this library is that apart from the prime function we seek, it offers flexibility and customization as well. The idea is to use this as a placeholder for a person&apos;s profile picture. For example if you take WhatsApp, you have a grayed contact icon which is rather dull. If the user had a profile picture, that would replace the grey icon instead. That&apos;s the same thing we&apos;re going to fix here, except instead of that boring grayed icon, we&apos;ll add a randomly generated color for our placeholder along with the 1st letter of the list item (as seen above).&lt;/p&gt;
&lt;h2&gt;Setup&lt;/h2&gt;
&lt;p&gt;As advertised, the library is lightweight and you can start using it simply by adding these lines to your &lt;strong&gt;build.gradle&lt;/strong&gt; file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;repositories {
    maven {
        url &apos;http://dl.bintray.com/amulyakhare/maven&apos;
    }
}

dependencies {
    compile &apos;com.amulyakhare:com.amulyakhare.textdrawable:1.0.1&apos;
    ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Layout&lt;/h2&gt;
&lt;p&gt;As always, we&apos;ll start with the &lt;strong&gt;MainActivity&lt;/strong&gt;&apos;s layout, which is nothing but a RecyclerView. So let&apos;s jump ahead to our list item&apos;s layout.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./create-gmail-style-list-in-android/list_item.png&quot; alt=&quot;list_item&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Modifying the &lt;a href=&quot;https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter.html&quot;&gt;Adapter&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now I won&apos;t be going into creating an adapter for our list. You can find tons of posts about that &lt;a href=&quot;http://www.vogella.com/tutorials/AndroidRecyclerView/article.html&quot;&gt;like this one&lt;/a&gt;. Moreover, as an Android developer, you must be both familiar and comfortable in creating an adapter for your RecyclerView by now. So instead of that, I&apos;ll show you how to modify our RecyclerView&apos;s adapter so we can get those different colors. Be sure to reference your ImageView (&lt;strong&gt;gmailitem_letter&lt;/strong&gt;) in your &lt;a href=&quot;https://developer.android.com/reference/android/support/v7/widget/RecyclerView.ViewHolder.html&quot;&gt;RecyclerView &lt;strong&gt;ViewHolder&lt;/strong&gt;&lt;/a&gt; like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class GmailVH extends RecyclerView.ViewHolder {
        ImageView letter;
        ...

        public GmailVH(View itemView) {
            super(itemView);
            letter = (ImageView) itemView.findViewById(R.id.gmailitem_letter);
            ...
        }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;a href=&quot;https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter.html#onBindViewHolder(VH,%20int)&quot;&gt;onBindViewHolder()&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Called by RecyclerView to display the data at the specified position.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is where we&apos;ll create a &lt;strong&gt;TextDrawable&lt;/strong&gt;, generate a random color for it and set it to our ImageView. To generate a random color, use &lt;code&gt;ColorGenerator generator = ColorGenerator.MATERIAL;&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; @Override
    public void onBindViewHolder(GmailVH gmailVH, int i) {
        ...
//        Get the first letter of list item
        letter = String.valueOf(dataList.get(i).charAt(0));

//        Create a new TextDrawable for our image&apos;s background
        TextDrawable drawable = TextDrawable.builder()
                .buildRound(letter, generator.getRandomColor());

        gmailVH.letter.setImageDrawable(drawable);
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I hope along with the comments, the above code snippet was self explanatory. For each list item for position &lt;strong&gt;int i&lt;/strong&gt;, we will be generating a random color for each list item. If you want instead of randomly generating colors, you can generate based on a key value like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int color = generator.getColor(&quot;urawesome@gmail.com&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, don&apos;t forget to set your adapter! Here&apos;s the entire adapter code if you need it, otherwise feel free to scroll past it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class GmailAdapter extends RecyclerView.Adapter {
    List dataList;
    String letter;
    Context context;
    ColorGenerator generator = ColorGenerator.MATERIAL;

    public GmailAdapter(Context context, List dataList) {
        this.context = context;
        this.dataList = dataList;
    }

    @Override
    public GmailVH onCreateViewHolder(ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.gmail_list_item, viewGroup, false);
        return new GmailVH(view);
    }

    @Override
    public void onBindViewHolder(GmailVH gmailVH, int i) {
        gmailVH.title.setText(dataList.get(i));
        letter = String.valueOf(dataList.get(i).charAt(0));

        TextDrawable drawable = TextDrawable.builder()
                .buildRound(letter, generator.getRandomColor());

        gmailVH.letter.setImageDrawable(drawable);
    }

    @Override
    public int getItemCount() {
        return dataList == null ? 0 : dataList.size();
    }

    class GmailVH extends RecyclerView.ViewHolder {
        TextView title;
        ImageView letter;

        public GmailVH(View itemView) {
            super(itemView);
            letter = (ImageView) itemView.findViewById(R.id.gmailitem_letter);
            title = (TextView) itemView.findViewById(R.id.gmailitem_title);
        }
    }

}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Final Output&lt;/h2&gt;
&lt;p&gt;Here&apos;s how its finally going to look like. Pretty neat eh?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./create-gmail-style-list-in-android/Screenshot-13-Aug-2015-6_18_01-pm.png&quot; alt=&quot;Screenshot (13 Aug 2015 6_18_01 pm)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;As always you can check out the code sample over at &lt;a href=&quot;https://github.com/Suleiman19/Android-Material-Design-for-pre-Lollipop/blob/master/MaterialSample/app/src/main/java/com/suleiman/material/activities/GmailStyleActivity.java&quot;&gt;GitHub&lt;/a&gt;. If you have a profile picture, you can easily handle that as well. Simple don&apos;t generate a TextDrawable, instead pass that image as the background for the ImageView. As you can see the library helped us give our RecyclerView a facelift. That&apos;s not all, the library has additional functionality which you can explore and add to your app as needed. Even the need for handling the entire list of colors is not needed, which is why this library is great for creating a Gmail style list. Hoping to see you put it to good use. Cheers!&lt;/p&gt;
</content:encoded></item><item><title>My Experience with the Moto G 3rd Gen</title><link>https://blog.iamsuleiman.com/my-experience-with-moto-g-3rd-gen/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/my-experience-with-moto-g-3rd-gen/</guid><description>I was looking to get a new phone for a while and wasn&apos;t sure what to get. I heard rumors about the Moto G 3rd gen (Moto G3), and decided to wait. The </description><pubDate>Wed, 05 Aug 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I was looking to get a new phone for a while and wasn&apos;t sure what to get. I heard rumors about the Moto G 3rd gen (Moto G3), and decided to wait. The wait was worth it. This is not a typical speculative review, but rather my hands-on experience, a week after buying and using the phone myself. :-) &lt;a href=&quot;https://blog.iamsuleiman.com/assets/images/my-experience-with-moto-g-3rd-gen/IMG_20150802_185000956.jpg&quot;&gt;&lt;/a&gt;   I bought the Moto G 3rd Gen 16GB internal, 2GB RAM variant, in black. I&apos;d suggest you go for the same too as there&apos;s not much you could do with the 8GB variant given there&apos;s only about 3.2GB free space remaining for you to play around with.&lt;/p&gt;
&lt;h2&gt;Build &amp;amp; Design&lt;/h2&gt;
&lt;p&gt;One can say Motorola has played it safe with the build here. Last year&apos;s model was pretty solid, and they&apos;ve improved upon that. The front speaker grille are less obtrusive and suit the phone&apos;s design well. &lt;a href=&quot;https://blog.iamsuleiman.com/assets/images/my-experience-with-moto-g-3rd-gen/g3_front-e1438786297979.jpg&quot;&gt;&lt;/a&gt; The back design is what I love. It sports a diagonally ribbed texture, along with a centered camera and two-tone flash, housed in a metallic strip. I particularly like this texture, including the power button. The strip accents the back very well, along with Motorola&apos;s logo. The overall back texture is a welcome addition, making me more confident while holding the phone. &lt;a href=&quot;https://blog.iamsuleiman.com/assets/images/my-experience-with-moto-g-3rd-gen/g3_back.jpg&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Water Resistance&lt;/h3&gt;
&lt;p&gt;Motorola even made the Moto G water resistant with a IPX7 rating. On paper it says the phone can withstand upto 1 feet for 30 minutes. However, its not designed to be used while underwater. &lt;a href=&quot;https://www.youtube.com/watch?v=pZsiUEtitqM&quot;&gt;Watch on YouTube&lt;/a&gt; The important thing to note here is, only original Motorola back cases will help with water resistance, provided the back is sealed properly. Not to worry as when you power on the phone first time, it will walk you through all this. I haven&apos;t personally tried this myself. Didn&apos;t want to subject my phone to such cruelty on day one. However, you&apos;re welcome to try it ;-) Overall the phone doesn&apos;t look cheap in any way. The build is solid and the phone feels firm to hold.&lt;/p&gt;
&lt;h2&gt;Display&lt;/h2&gt;
&lt;p&gt;I don&apos;t ask for much in terms of display here. Motorola stuck with the Moto G2&apos;s display, going at 5-inch HD (720x1280p) display (entire specs &lt;a href=&quot;http://www.gsmarena.com/motorola_moto_g_(3rd_gen)-7247.php&quot;&gt;here&lt;/a&gt;). I&apos;m satisfied with this. The display is good, though not too sharp as full-HD displays. Nothing to complain here. In fact this would only do good for the battery. Motorola&apos;s added an on screen display (notification) feature, which in my opinion is pretty neat. You can view all your notifications, and control your music without having to unlock your phone, each and every time. Neat! Touch response is excellent. I carry out my daily tasks such as email, texting, social media, light gaming with my Wi-Fi on the whole time. No hiccups or lag whatsoever. You might want to keep a screen guard ready for your new Moto G3. I know it comes with Corning Gorilla Glass, but you can never be too safe. Moreover, you&apos;ll get a screen cover like this: &lt;a href=&quot;https://blog.iamsuleiman.com/assets/images/my-experience-with-moto-g-3rd-gen/DSC_1706.jpg&quot;&gt;&lt;/a&gt; Naturally you might want to replace that ASAP.&lt;/p&gt;
&lt;h2&gt;Software&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;No bloatware. Stock Android. Moto apps.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That said it all. I&apos;m happy to see my homescreen free of useless apps. Motorola&apos;s set of installed apps improve upon the already brilliant user experience. There are 3 features bundled into the Moto app:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./my-experience-with-moto-g-3rd-gen/Screenshot_2015-08-02-15-33-54.png&quot; alt=&quot;Screenshot_2015-08-02-15-33-54&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Assist&lt;/h3&gt;
&lt;p&gt;helps tailor your phones audio settings depending on what you&apos;re doing or where you are. For instance if you&apos;re in a meeting, it can silent all calls. If you wish your favourite contacts can still get to you on the second ring.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./my-experience-with-moto-g-3rd-gen/Screenshot_2015-08-02-15-35-00.png&quot; alt=&quot;Screenshot_2015-08-02-15-35-00&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./my-experience-with-moto-g-3rd-gen/Screenshot_2015-08-02-15-35-13.png&quot; alt=&quot;Screenshot_2015-08-02-15-35-13&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Action&lt;/h3&gt;
&lt;p&gt;Two neat gestures, a double karate chop for torch and twist twice to open the Camera.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./my-experience-with-moto-g-3rd-gen/Screenshot_2015-08-02-15-35-21.png&quot; alt=&quot;Screenshot_2015-08-02-15-35-21&quot; /&gt;&lt;/p&gt;
&lt;p&gt;You can even twist twice, to switch back and forth between the front and rear camera. The good news is these gestures work as said, quite well.&lt;/p&gt;
&lt;h3&gt;Display&lt;/h3&gt;
&lt;p&gt;The screen wakes to display notifications, that you can view without unlocking your phone. You can tailor this by picking which apps you don&apos;t need a notification and so on.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./my-experience-with-moto-g-3rd-gen/Screenshot_2015-08-02-15-35-27.png&quot; alt=&quot;Screenshot_2015-08-02-15-35-27&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Camera&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;13MP rear, 5MP front camera. Fast shutter. Need I say more?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Motorola has steadily been working on the camera. The G had 5MP, G2 had 8MP and G3 has 13. Motorola says the G3 uses the same camera module used in Nexus 6. While that sounds good on paper, that&apos;s not the case really. Images snapped under well-lit conditions (daylight) are brilliant, while low light images are decent, they tend to suffer from noise. Especially if you prefer taking a snap without flash, like me. However, the two-tone flash built in is good. The shutter is very fast even if you turn on HDR, that&apos;s great news, complemented with a top-notch and clean camera UI, that makes taking photos with the Moto G3 a breeze. Here are some random shots I&apos;ve taken (under various conditions) for you to judge.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./my-experience-with-moto-g-3rd-gen/IMG_20150804_201625848.jpg&quot; alt=&quot;Moto G3 camera sample 1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./my-experience-with-moto-g-3rd-gen/IMG_20150804_201634510.jpg&quot; alt=&quot;Moto G3 camera sample 2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./my-experience-with-moto-g-3rd-gen/IMG_20150804_201642265.jpg&quot; alt=&quot;Moto G3 camera sample 3&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./my-experience-with-moto-g-3rd-gen/IMG_20150804_061040882.jpg&quot; alt=&quot;Moto G3 camera sample 4&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./my-experience-with-moto-g-3rd-gen/IMG_20150804_061059426_HDR.jpg&quot; alt=&quot;Moto G3 camera sample 5, HDR&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./my-experience-with-moto-g-3rd-gen/IMG_20150803_181845747.jpg&quot; alt=&quot;Moto G3 camera sample 6&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./my-experience-with-moto-g-3rd-gen/IMG_20150802_161433625.jpg&quot; alt=&quot;Moto G3 camera sample 7&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Battery&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Moto G3 packs a 2470 mAh battery.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Personally I felt this was low, but I was wrong. The phone lasts remarkably well. I use this throughout the day with Wi-Fi on the entire time, browsing, emails, various social media, gaming and taking lots of photos. End of the day I have about 30% left. Oh, and did I mention I charged it the previous night? To me, that&apos;s good enough.&lt;/p&gt;
&lt;h2&gt;Verdict&lt;/h2&gt;
&lt;p&gt;What I learn from all this is that &quot;&lt;strong&gt;Hardware specs aren&apos;t everything in a phone&lt;/strong&gt;&quot;. The phone is snappy, performs great. No signs of lag whatsoever. Good camera (fast shutter). Water resistance is a welcome addition. Butter smooth, bloat-free Android Lollipop. Need I say more?&lt;/p&gt;
&lt;h3&gt;Pros:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Lag-free experience&lt;/li&gt;
&lt;li&gt;Solid phone design&lt;/li&gt;
&lt;li&gt;Water resistant&lt;/li&gt;
&lt;li&gt;Customizable via Moto Maker&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Cons:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Good camera, but not great&lt;/li&gt;
&lt;li&gt;No fast charging&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Should you buy it?&lt;/h2&gt;
&lt;p&gt;For India, you can &lt;a href=&quot;http://dl.flipkart.com/dl/moto-g-3rd-generation/p/itme9ysjfazgqyqz?pid=MOBE6KK9K4HX5WTN&amp;amp;affid=suleimana&quot;&gt;buy Moto G (3rd Gen)&lt;/a&gt; from Flipkart. They did a damn good job of delivering it. &lt;a href=&quot;http://www.amazon.com/gp/product/B00ZQVSKSM/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=B00ZQVSKSM&amp;amp;linkCode=as2&amp;amp;tag=graartblo-20&amp;amp;linkId=6CN7CJ5C2PU7DDX5&quot;&gt;Or purchase one from Amazon.&lt;/a&gt;If you&apos;re looking for a budget phone, look no further. The Moto G 3rd Gen is an all round performer. Whatever it does, it does well. Motorola shows others, this is how you make a budget phone! It does it in style and shows what&apos;s possible at this price range.  When Motorola launched this phone, their slogan was &quot;&lt;strong&gt;Choose the phone that&apos;s always there for you&lt;/strong&gt;&quot;, and I&apos;d support that. Even the cons mentioned above is no deal-breaker, that&apos;s just me nitpicking. I chose this phone over the Zenfone 2, Galaxy J5, K3 Note and Mi 4i. I don&apos;t regret my decision one bit. If you want a phone that performs, has a quick camera, is bloat-free, will last and gives timely updates, then Moto G 3rd Gen is the phone for you.&lt;/p&gt;
</content:encoded></item><item><title>Make an Android Splash Screen (Launch Screen)</title><link>https://blog.iamsuleiman.com/android-launch-screen-splash-screen/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/android-launch-screen-splash-screen/</guid><description>The launch screen (or splash screen if you prefer), is the first thing your user&apos;s going to see. In other words, it is a user&apos;s first experience of yo</description><pubDate>Fri, 31 Jul 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The launch screen (or splash screen if you prefer), is the first thing your user&apos;s going to see. In other words, it is a user&apos;s first experience of your application. In this post I&apos;ll show you how to create a branded launch screen / splash screen for your Android apps.&lt;/p&gt;
&lt;p&gt;This is where you must do your best to impress the user. Use some flashy graphics, vibrant imagery along with a neat logo. Not trying to be harsh, but if you slack off here, he&apos;s probably not going to return.&lt;/p&gt;
&lt;p&gt;Here are a few examples to inspire you.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-launch-screen-splash-screen/all-splash-screen_inspiration-e1438259834537-744x335.png&quot; alt=&quot;all-splash-screen_inspiration&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Why use a Launch / Splash Screen?&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;The launch screen is a user’s first experience of your application.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can take this opportunity to briefly provide brand exposure, as a welcome screen. However, I suggest you have a more useful purpose than JUST this.&lt;/p&gt;
&lt;p&gt;If your app is heavily dependent on data that would take a while to load, say you&apos;re downloading images from a database, loading a URL or fetching information from a server. Without this your initial UI will look empty and increase it&apos;s  perceived loading time.&lt;/p&gt;
&lt;p&gt;Such situations are a perfect for a launch screen. Use this opportunity to load data in the background. So while your launch screen is being displayed, a background task will be fetching the required data for your app.&lt;/p&gt;
&lt;h3&gt;Types of Launch Screens&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&quot;http://www.google.co.in/design/spec/patterns/launch-screens.html&quot;&gt;launch screen&lt;/a&gt; as mentioned by Material Design has two types:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Branded Launch&lt;/strong&gt; -  provide momentary brand exposure, freeing the UI to focus on content&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Placeholder UI&lt;/strong&gt; - for apps that have very short load times, or don’t have a strong branding need&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can read more about these &lt;a href=&quot;http://www.google.co.in/design/spec/patterns/launch-screens.html#&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Now I&apos;ll show you how to make a branded launch screen, and how to use this opportunity to carry out your background tasks.&lt;/p&gt;
&lt;h2&gt;Branded Launch Screen&lt;/h2&gt;
&lt;p&gt;Create a new Blank Activity named &lt;strong&gt;LaunchScreenActivity&lt;/strong&gt; and set this to be the Launch Activity. Check the &lt;strong&gt;AndroidManifest.xml&lt;/strong&gt; and it should be like this:&lt;/p&gt;
&lt;p&gt;...


&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;           &amp;lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /&amp;gt;
       &amp;lt;/intent-filter&amp;gt;
   &amp;lt;/activity&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;...&lt;/p&gt;
&lt;h3&gt;Layout&lt;/h3&gt;
&lt;p&gt;This is where we&apos;ll design our actual launch screen. This could entirely be an image, or you could do the layout using Android&apos;s native XML as well. For this demo, I&apos;ll simply use a nice Material Design wallpaper of my choice, followed by a centered title.&lt;/p&gt;
&lt;p&gt;Here&apos;s the layout structure for reference:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;FrameLayout 
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    android:background=&quot;@color/blue_grey&quot; &amp;gt;

      &amp;lt;ImageView
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;match_parent&quot;
        android:background=&quot;@drawable/splash_img&quot; /&amp;gt;

    &amp;lt;LinearLayout
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_gravity=&quot;center&quot;
        android:orientation=&quot;vertical&quot;&amp;gt;

        &amp;lt;TextView
            android:text=&quot;Material Design&quot; /&amp;gt;

        &amp;lt;TextView
            android:text=&quot;Sample App&quot; /&amp;gt;
    &amp;lt;/LinearLayout&amp;gt;

&amp;lt;/FrameLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./android-launch-screen-splash-screen/launch-screen.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;layout.xml preview&lt;/p&gt;
&lt;p&gt;Once you&apos;re done making your awesome launch screen, head over to your Activity.&lt;/p&gt;
&lt;h3&gt;Launch Screen Activity&lt;/h3&gt;
&lt;p&gt;Remember I mentioned about carrying out a background task while displaying the launch screen to users? This is where we&apos;re going to do that.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class LaunchScreenActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        new BackgroundTask().execute();
        ...
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the &lt;strong&gt;BackgroundTask()&lt;/strong&gt;. This is an &lt;a href=&quot;http://developer.android.com/reference/android/os/AsyncTask.html&quot;&gt;AsyncTask&lt;/a&gt; which you will use to carry out your background tasks. However, I will simply use a timer, which upon a 3 second completion will go to your app&apos;s home activity.&lt;/p&gt;
&lt;h4&gt;Background AsyncTask&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;private class BackgroundTask extends AsyncTask {
        Intent intent;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            intent = new Intent(LaunchScreenActivity.this, MainActivity.class);
        }

        @Override
        protected Object doInBackground(Object[] params) {

            /*  Use this method to load background
            * data that your app needs. */

            try {
                Thread.sleep(SPLASH_TIME);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            return null;
        }

        @Override
        protected void onPostExecute(Object o) {
            super.onPostExecute(o);
//            Pass your loaded data here using Intent

//            intent.putExtra(&quot;data_key&quot;, &quot;&quot;);
            startActivity(intent);
            finish();
        }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the 3 methods here. The &lt;strong&gt;onPreExecute()&lt;/strong&gt; must be used for initialization. To prepare whatever you need to carry out your task. The &lt;strong&gt;doInBackground()&lt;/strong&gt; is where the actual background task will be carried out. The meat of the task happens here. Finally, use the &lt;strong&gt;onPostExecute()&lt;/strong&gt; method to carry out whatever needs to be done AFTER our task is complete.&lt;/p&gt;
&lt;p&gt;In our case, we will use onPostExecute to send the user to our app&apos;s home screen (Activity). Use this chance to pass the fetched data via an &lt;a href=&quot;http://www.vogella.com/tutorials/AndroidIntent/article.html&quot;&gt;Intent&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Yep, that&apos;s pretty much it! However do note that in my case, I am simply using a 3 second timer, which upon expiring takes the user to the home screen. You should do something more useful here.&lt;/p&gt;
&lt;p&gt;Also, if your background tasks may take longer to execute, consider adding a ProgressBar or Spinner to indicate some sort of progress to the user. Otherwise they may be staring at your launch screen for quite a while not knowing what&apos;s going on. Visual feedback is important!&lt;/p&gt;
&lt;p&gt;Anyway, here&apos;s the demo.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/nZ8DWoJYhPM&quot;&gt;Watch on YouTube&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As always, here a link to &lt;a href=&quot;https://github.com/Suleiman19/Android-Material-Design-for-pre-Lollipop/blob/master/MaterialSample/app/src/main/java/com/suleiman/material/activities/LaunchScreenActivity.java&quot;&gt;GitHub&lt;/a&gt; for code sample.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;A launch screen is a recent addition in Google&apos;s Material Design arsenal for Android apps. While its certainly not new, with major app brands doing this for a long time. Only now do we have some official confirmation about this being a valid design pattern.&lt;/p&gt;
&lt;p&gt;While my two minute launch screen design is far from amazing, it only serves the purpose of a demo. I believe you could come up with something much better. Drop &apos;em in the comments below!&lt;/p&gt;
</content:encoded></item><item><title>Pinterest Masonry Layout (Staggered Grid)</title><link>https://blog.iamsuleiman.com/pinterest-masonry-layout-staggered-grid/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/pinterest-masonry-layout-staggered-grid/</guid><description>If you have used the Pinterest app or their website, you would have noticed a rather creative grid layout. That is a Masonry Layout. &gt; It works by pla</description><pubDate>Mon, 27 Jul 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you have used the Pinterest app or their website, you would have noticed a rather creative grid layout. That is a Masonry Layout.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It works by placing elements in optimal position based on available vertical space, sort of like a mason fitting stones in a wall.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./pinterest-masonry-layout-staggered-grid/pinterest-masonry-744x367.png&quot; alt=&quot;My Pinterest home feed&quot; title=&quot;My Pinterest home feed&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Thankfully, we won&apos;t be needing any external library for this as Android&apos;s native RecyclerView makes implementing a Pinterest masonry layout simply by changing the RecyclerView&apos;s Layout Manager. This is quite popular in web design as well. Let&apos;s look at implementing this in Android.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Start by adding the require Gradle dependencies.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dependencies {
    compile &apos;com.android.support:appcompat-v7:22.2.1&apos;
    compile &apos;com.android.support:recyclerview-v7:22.2.1&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Masonry Layout - Tile&lt;/h2&gt;
&lt;p&gt;Now for each tile I will use a simple LinearLayout, however you could alternatively use a Card view.&lt;/p&gt;
&lt;p&gt;Nothing fancy up there. Just an ImageView and a TextView for a title. This is the layout for each of our tile. Now this is akin to each list item in your typical ListView. I am purposely skipping our &lt;strong&gt;MainActivity&lt;/strong&gt;&apos;s layout since its just a RecyclerView. We&apos;ll skip that and head onto creating our adapter and hooking it up to our RecyclerView.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./pinterest-masonry-layout-staggered-grid/staggered-grid-tile.png&quot; alt=&quot;staggered grid tile&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Adapter&lt;/h2&gt;
&lt;p&gt;If you&apos;re familiar with custom ListView in the past, you should be aware of a ViewHolder. This is basically the layout for EACH item in our list.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; class MasonryView extends RecyclerView.ViewHolder {
        ImageView imageView;
        TextView textView;

        public MasonryView(View itemView) {

            imageView = (ImageView) itemView.findViewById(R.id.img);
            textView = (TextView) itemView.findViewById(R.id.img_name);

        }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we need to create our RecyclerView&apos;s adapter and tell it to use this ViewHolder of ours.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class MasonryAdapter extends RecyclerView.Adapter {
    private Context context;

    int[] imgList = {R.drawable.two, R.drawable.one, R.drawable.three, R.drawable.four,
            R.drawable.five, R.drawable.six, R.drawable.seven, R.drawable.eight,
            R.drawable.nine, R.drawable.ten};

    String[] nameList = {&quot;One&quot;, &quot;Two&quot;, &quot;Three&quot;, &quot;Four&quot;, &quot;Five&quot;, &quot;Six&quot;,
            &quot;Seven&quot;, &quot;Eight&quot;, &quot;Nine&quot;, &quot;Ten&quot;};

    public MasonryAdapter(Context context) {
        this.context = context;
    }

    @Override
    public MasonryView onCreateViewHolder(ViewGroup parent, int viewType) {
        View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.grid_item, parent, false);
        MasonryView masonryView = new MasonryView(layoutView);
        return masonryView;
    }

    @Override
    public void onBindViewHolder(MasonryView holder, int position) {
        holder.imageView.setImageResource(imgList[position]);
        holder.textView.setText(nameList[position]);
    }

    @Override
    public int getItemCount() {
        return nameList.length;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nothing much to explain here, except that its our regular RecyclerView adapter. Nothing out of the ordinary, I&apos;m pretty sure everyone&apos;s familiar with this by now. To populate my Staggered Grid, I&apos;m simply using 10 random images loaded from my &lt;strong&gt;drawable&lt;/strong&gt; folder, named one to ten.&lt;/p&gt;
&lt;h2&gt;Attaching the Adapter&lt;/h2&gt;
&lt;p&gt;With all that set, all that is needed is to attach this created adapter of ours to our RecyclerView. Note that the key here is the &lt;a href=&quot;https://developer.android.com/reference/android/support/v7/widget/RecyclerView.LayoutManager.html&quot;&gt;LayoutManager&lt;/a&gt;. This helps determine the layout of our RecyclerView. It could be a regular list, a uniform grid, or a staggered grid (which is what we what). This can further be defined to be scrollable either horizontally or vertically.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));

        MasonryAdapter adapter = new MasonryAdapter(this);
        mRecyclerView.setAdapter(adapter);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, the parameters for the &lt;a href=&quot;https://developer.android.com/reference/android/support/v7/widget/StaggeredGridLayoutManager.html&quot;&gt;StaggeredGridLayoutManager&lt;/a&gt; is the number of columns and orientation respectively. That&apos;s all that&apos;s needed to be done. Nothing fancy or out of the ordinary here. If you&apos;re quite familiar with RecyclerView, you would realize that the only thing that needs to be changed is the LayoutManager that should be used is a &lt;strong&gt;StaggeredGridLayoutManager&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;Staggered Grid Spacing Fix&lt;/h2&gt;
&lt;p&gt;Great so its done. Before you run along and test your app, let me stop you right there and ask you to include a tiny fix. The issue is that, while I was building my sample, I noticed that setting a &lt;strong&gt;margin&lt;/strong&gt; on my LinearLayout didn&apos;t seem to work. There was no spacing between my tiles which made the entire list appear joined. This obviously is not what we want. So here&apos;s a quick fix. Create a new class that extends &lt;strong&gt;RecyclerView.ItemDecoration&lt;/strong&gt; that helps add spacing around each tile. You might remember that ItemDecoration helps add things like a list divider for each row item.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class SpacesItemDecoration extends RecyclerView.ItemDecoration {
    private final int mSpace;

    public SpacesItemDecoration(int space) {
        this.mSpace = space;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        outRect.left = mSpace;
        outRect.right = mSpace;
        outRect.bottom = mSpace;

        // Add top margin only for the first item to avoid double space between items
        if (parent.getChildAdapterPosition(view) == 0)
            outRect.top = mSpace;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now just tell our RecyclerView to add this ItemDivider simply:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SpacesItemDecoration decoration = new SpacesItemDecoration(16);
mRecyclerView.addItemDecoration(decoration);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Feel free to add any value you wish for &lt;strong&gt;SpacesItemDecoration&lt;/strong&gt;. That value determines the amount of spacing.&lt;/p&gt;
&lt;h2&gt;Final Results&lt;/h2&gt;
&lt;p&gt;I&apos;m not going to stop you from running the app now, so go ahead and run it!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./pinterest-masonry-layout-staggered-grid/staggered-grid.png&quot; alt=&quot;staggered grid&quot; /&gt;&lt;/p&gt;
&lt;p&gt;As always, here&apos;s the &lt;a href=&quot;https://github.com/Suleiman19/Masonry&quot;&gt;GitHub link&lt;/a&gt; for the source code.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;RecyclerView is pretty powerful as you can see. We were able to create a Pinterest masonry layout using a StaggeredGridLayoutManager. It is more flexible that the previous ListView (which I still see a few people using) and strongly suggest you migrate to its better alternative. Its brilliant how just by changing the LayoutManager, we were able the change the face of a regular RecyclerView to come up with something creative.&lt;/p&gt;
</content:encoded></item><item><title>Top 10 Material Design Libraries for Android</title><link>https://blog.iamsuleiman.com/top-10-material-design-libraries-for-android/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/top-10-material-design-libraries-for-android/</guid><description>Material Design is all the rage now. Here are top 10 libraries you need to provide a complete Material Design experience across all apps, pre Lollipop</description><pubDate>Mon, 20 Jul 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Material Design is all the rage now. Here are top 10 libraries you need to provide a complete Material Design experience across all apps, pre Lollipop as well. These are in no order of priority.&lt;/p&gt;
&lt;h2&gt;1. Android Design Support Library&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Provides APIs to support adding material design components and patterns to your apps. It adds support for various material design components and patterns such as navigation drawers, floating action buttons (&lt;em&gt;FAB&lt;/em&gt;), snackbars, and tabs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This library has come a long way from its initial release.  It provides a ton of useful stuff that would otherwise take time to do. Animations like quick return can be done just by XML alone. I encourage devs to give this one a go before resorting to another external library for the same. The good news is that everything that this library provides is pre Lollipop compatible. Here are some of the Material Design components the library provides:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Navigation Drawer&lt;/li&gt;
&lt;li&gt;Floating Action Button&lt;/li&gt;
&lt;li&gt;Toolbar (Flexible Space with Image Pattern, Quick Return, etc)&lt;/li&gt;
&lt;li&gt;Material Design Tabs&lt;/li&gt;
&lt;li&gt;Bottom Sheets&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can get started by adding this to your &lt;strong&gt;build.gradle&lt;/strong&gt;&apos;s dependency: &lt;code&gt;com.android.support:design:23.2.0&lt;/code&gt; You can check out the &lt;a href=&quot;http://android-developers.blogspot.in/2015/05/android-design-support-library.html&quot;&gt;developer&apos;s blog&lt;/a&gt; for an intro. ALSO READ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/bottom-sheet-android-design-support-library/&quot;&gt;Add a Bottom Sheet to your apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/toolbar-animation-with-android-design-support-library/&quot;&gt;Implement a Toolbar Animation (Flexible Space with Image)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/material-design-tabs-with-android-design-support-library/&quot;&gt;Material Design Tabs Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/easy-navigation-drawer-with-design-support-library/&quot;&gt;Easy Material Design Navigation Drawer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;2. Circular Reveal&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Reveal animations provide users visual continuity when you show or hide a group of UI elements.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/top-10-material-design-libraries-for-android/reveal-effect-final.gif&quot; alt=&quot;reveal-effect-final&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This was introduced in Lollipop and is specific to that too. But this library allows us to have the same animation ported to previous Android versions too. Neat! The advantage is the syntax and methods are exactly the same. So you can get started right away. My &lt;a href=&quot;https://blog.iamsuleiman.com/circular-reveal-effect-like-whatsapp-in-android/&quot;&gt;post&lt;/a&gt; on this should show you how it works. &lt;strong&gt;LIBRARY:&lt;/strong&gt; &lt;a href=&quot;https://github.com/ozodrukh/CircularReveal&quot;&gt;Circular Reveal by ozodrukh&lt;/a&gt; ALSO READ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/bottom-navigation-bar-android-tutorial/&quot;&gt;Create a Reveal Effect in Android (like WhatsApp)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;3. Floating Action Button (Expandable)&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Floating action buttons are used for a promoted action.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/top-10-material-design-libraries-for-android/menu.gif&quot; alt=&quot;menu&quot; /&gt;&lt;/p&gt;
&lt;p&gt;While the Design Support Library does provide you a Floating Action Button (FAB), this one deserves a mention for it&apos;s expand and collapse ability. You might have noticed this in the Google Keep app. So if you need that expand ability on your FAB, this is the go to library. It&apos;s can be easily customized and should get you up in a couple of minutes at most. &lt;strong&gt;LIBRARY:&lt;/strong&gt; &lt;a href=&quot;https://github.com/futuresimple/android-floating-action-button&quot;&gt;Android Floating Action Button by futuresimple&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;4. Material Navigation Drawer&lt;/h2&gt;
&lt;p&gt;Yes we got this too, but here&apos;s the difference.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./top-10-material-design-libraries-for-android/drawer.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./top-10-material-design-libraries-for-android/screenshot1_small.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Maybe you&apos;re not satisfied with the Design Support. You want more, like the one on the right? Full control over the nav links, include a button or a switch there? Then this library by mikepenz is for you. It includes full drawer customization. Includes sections, header with images, account switcher and dark/ light themes too. &lt;strong&gt;LIBRARY:&lt;/strong&gt; &lt;a href=&quot;https://github.com/mikepenz/MaterialDrawer&quot;&gt;Material Drawer by mikepenz&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;5. Ripple Effect Backport&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Touch feedback in material design provides an instantaneous visual confirmation at the point of contact when users interact with UI elements. The default touch feedback animations for buttons use the new RippleDrawable class, which transitions between different states with a ripple effect.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/top-10-material-design-libraries-for-android/demo.gif&quot; alt=&quot;demo&quot; /&gt;&lt;/p&gt;
&lt;p&gt;What would Material Design be without this neat effect? This too has been exclusive for Lollipop and above. Thanks to this library, we can do a similar effect on pre Lollipop versions. &lt;strong&gt;LIBRARY:&lt;/strong&gt; &lt;a href=&quot;https://github.com/traex/RippleEffect&quot;&gt;Ripple Effect by traex&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;6. Lollipop Transitions Backport&lt;/h2&gt;
&lt;p&gt;Transitions since Lollipop have been overhauled, and I must say that they are brilliant. The shared transitions and the way each element loads into each new Activity is amazing. Unfortunately this yet again was Lollipop only, but the GitHub user andkulikov has backported the Transitions API from Kitkat and Lollipop for API 2.2 above. &lt;strong&gt;LIBRARY:&lt;/strong&gt; &lt;a href=&quot;https://github.com/andkulikov/transitions-everywhere&quot;&gt;Transitions Everywhere by andkulikov&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;7. Bottom Navigation Bar&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Bottom navigation bars make it easy to explore and switch between top-level views in a single tap.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/top-10-material-design-libraries-for-android/bottom-navigation-bar-output.gif&quot; alt=&quot;bottom navigation bar output&quot; /&gt;&lt;/p&gt;
&lt;p&gt;A relative new addition to Material Design&apos;s arsenal. Akin to the TabLayout seen on iOS. This type of navigation is very popular on iOS apps. In Android, it works as a regular Bottom Bar on mobile. Switches to a side navigation on Tablets. This is really neat, and I&apos;m excited to see how developers put it to good use. Its ideal for apps that have only three to four navigation screens. Makes sense to use Bottom Navigation, instead of a Navigation Drawer then. &lt;strong&gt;LIBRARY:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/aurelhubert/ahbottomnavigation&quot;&gt;Bottom Navigation by aurelhubert&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/roughike/BottomBar&quot;&gt;Bottom Bar by roughike&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ALSO READ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/bottom-navigation-bar-android-tutorial/&quot;&gt;Android Tutorial for Bottom Navigation Bar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;8. Super RecyclerView&lt;/h2&gt;
&lt;p&gt;While not a direct feature of Material Design, RecyclerView is replacing ListView, as something more versatile and powerful. Super RecyclerView is RecyclerView on steroids. As stated by the creator &quot;This is an attempt to make RecyclerView easier to use.&quot; It has a lot of features you might otherwise spend quite a while making. Some of them are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Swipe to Refresh (Google style)&lt;/li&gt;
&lt;li&gt;Swipe to Dismiss&lt;/li&gt;
&lt;li&gt;Infinite Scrolling&lt;/li&gt;
&lt;li&gt;Sticky Header&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;LIBRARY:&lt;/strong&gt; &lt;a href=&quot;https://github.com/Malinskiy/SuperRecyclerView&quot;&gt;Super RecyclerView by Malinskiy&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;9. Circular Image View&lt;/h2&gt;
&lt;p&gt;A circular image is very popular and Material Design has pushed this even further. But doing this in Android was never that straightforward. Thankfully, many libraries have made this dead simple to implement, yet versatile in nature. Such a library is one very popular library that has good draw performance as well. &lt;strong&gt;LIBRARY:&lt;/strong&gt; &lt;a href=&quot;https://github.com/hdodenhof/CircleImageView&quot;&gt;Circle Image View by hdodenhof&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;10. Material Shadows&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/top-10-material-design-libraries-for-android/images&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Shadows help define elevation of views. This is fundamental in the concept of Material Design. Sadly Lollipop uses a separate Render Thread to handle the UI, making such visuals not possible on pre Lollipop. However, GitHub user h6ah4i has managed to mimic this for API 9+ by using a 9-patch shadow image to replicate the feel of elevation for varying depths. &lt;strong&gt;LIBRARY:&lt;/strong&gt; &lt;a href=&quot;https://github.com/h6ah4i/android-materialshadowninepatch&quot;&gt;Android Material Shadow Nine patch by h6ah4i&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;These are MY top 10 Material Design libraries for enhancing the experience for my users. The recent Design Support Library by Android has added a LOT of features for our apps. But there are a lot of third party libraries which have made development a breeze. Like the ones above. So what are your favorite Material Design libraries? Did I miss anything? Let me know in the comments below.&lt;/p&gt;
</content:encoded></item><item><title>Circular Reveal Effect like WhatsApp in Android</title><link>https://blog.iamsuleiman.com/circular-reveal-effect-like-whatsapp-in-android/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/circular-reveal-effect-like-whatsapp-in-android/</guid><description>While sending a photo through WhatsApp, I noticed the &apos;Attach&apos; button performs a neat Circular Reveal effect. My phone being JellyBean, I was surprise</description><pubDate>Fri, 17 Jul 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;While sending a photo through WhatsApp, I noticed the &apos;Attach&apos; button performs a neat Circular Reveal effect. My phone being JellyBean, I was surprised to see a Lollipop only transition. Thanks to a neat library, we can mimic the exact same thing for pre Lollipop too.&lt;/p&gt;
&lt;h2&gt;The Reveal Effect&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Touch feedback in material design provides an instantaneous visual confirmation at the point of contact when users interact with UI elements.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The Reveal Effect uses the &lt;a href=&quot;https://developer.android.com/reference/android/graphics/drawable/RippleDrawable.html&quot;&gt;RippleDrawable&lt;/a&gt; class to achieve this. So visually, you can tell that it is similar to the Ripple effect. The only difference being that a Ripple is a touch feedback denoted by a color spreading from a point of contact, while the Reveal effect does the same animation, but for displaying a view.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WhatsApp&apos;s Version&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Here&apos;s how it looks on WhatsApp, after their Material Design upgrade.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./circular-reveal-effect-like-whatsapp-in-android/whatsapp-reveal-effect.png&quot; alt=&quot;whatsapp-reveal-effect&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This is exactly what we&apos;re going to create. If you still don&apos;t get what I&apos;m talking about then scroll down to the end of the post.&lt;/p&gt;
&lt;h2&gt;Setup&lt;/h2&gt;
&lt;p&gt;The issue is, this animation as said before is intended for Lollipop and above ONLY. There is no support library to help us out here. So no version below Lollipop can perform this.&lt;/p&gt;
&lt;p&gt;However, there is a neat &lt;a href=&quot;https://github.com/ozodrukh/CircularReveal&quot;&gt;library&lt;/a&gt; that&apos;s managed to backport this for us. We will be using the same, for our purpose. The good thing about the library is that, the methods are exactly the same, which is convenient. Though one must be careful about the imports.&lt;/p&gt;
&lt;h3&gt;Circular Reveal Library&lt;/h3&gt;
&lt;p&gt;We&apos;ll start by including the library in our &lt;strong&gt;build.gradle&lt;/strong&gt; file. Add the repository first, and then the dependency.&lt;/p&gt;
&lt;p&gt;repositories {
maven {
url &quot;&lt;a href=&quot;https://jitpack.io&quot;&gt;https://jitpack.io&lt;/a&gt;&quot;
}
}&lt;/p&gt;
&lt;p&gt;dependencies {
compile &apos;com.github.ozodrukh:CircularReveal:1.1.0&apos;
}&lt;/p&gt;
&lt;h3&gt;Layout&lt;/h3&gt;
&lt;p&gt;Let&apos;s create a layout similar to that of WhatsApp&apos;s Attach option.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./circular-reveal-effect-like-whatsapp-in-android/layout-2015-07-17-092633-420x736.png&quot; alt=&quot;layout-2015-07-17-092633&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Here&apos;s the layout skeleton if you&apos;re interested. Honestly this layout could be any layout that you want to reveal using this effect, even entire screen transitions could be done.&lt;/p&gt;
&lt;p&gt;&amp;lt;io.codetail.widget.RevealFrameLayout
android:layout_width=&quot;match_parent&quot;
android:layout_height=&quot;wrap_content&quot;&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;       &amp;lt;LinearLayout
           android:id=&quot;@+id/reveal_items&quot;
           android:layout_width=&quot;match_parent&quot;
           android:layout_height=&quot;wrap_content&quot;
           android:orientation=&quot;horizontal&quot;  &amp;gt;

           &amp;lt;LinearLayout
               android:layout_width=&quot;0dp&quot;
               android:layout_height=&quot;wrap_content&quot;
               android:layout_weight=&quot;1&quot;
               android:gravity=&quot;center&quot;
               android:orientation=&quot;vertical&quot;&amp;gt;

               &amp;lt;ImageButton
                   android:layout_width=&quot;70dp&quot;
                   android:layout_height=&quot;70dp&quot;
                   android:background=&quot;@drawable/icon_camera&quot; /&amp;gt;

               &amp;lt;TextView
                   android:layout_width=&quot;wrap_content&quot;
                   android:layout_height=&quot;wrap_content&quot;
                   android:layout_marginTop=&quot;16dp&quot;
                   android:text=&quot;Gallery&quot; /&amp;gt;
           &amp;lt;/LinearLayout&amp;gt;

           &amp;lt;!-- Other 2 icons here--&amp;gt;
           
       &amp;lt;/LinearLayout&amp;gt;

   &amp;lt;/io.codetail.widget.RevealFrameLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the &lt;strong&gt;RevealFrameLayout&lt;/strong&gt; widget. This comes from the library we imported. This is nothing but a FrameLayout. To perform the animation, we will reference the immediate child layout of this frame. While that child (here being the LinearLayout) with id &lt;strong&gt;reveal_items&lt;/strong&gt; will animate, it&apos;s shape will be clipped by the outer RevealFrameLayout.&lt;/p&gt;
&lt;h3&gt;Performing the Reveal Effect&lt;/h3&gt;
&lt;p&gt;Head over to your &lt;strong&gt;Activity.java&lt;/strong&gt; and lets get that animation working. The animation will be toggled when we tap the Attach (clip) button. The contents of the &lt;strong&gt;RevealFrameLayout&lt;/strong&gt; will be displayed, and hidden alternatively.&lt;/p&gt;
&lt;p&gt;Remember I said we need to reference the immediate child of the RevealFrameLayout.&lt;/p&gt;
&lt;p&gt;LinearLayout mRevealView = (LinearLayout) findViewById(R.id.reveal_items);
mRevealView.setVisibility(View.INVISIBLE);&lt;/p&gt;
&lt;p&gt;The view will be inivisible as by default it remains hidden, only presenting itself when we tap Attach.&lt;/p&gt;
&lt;p&gt;Our Attach button will be in our Toolbar, included using a menu resource.&lt;/p&gt;
&lt;p&gt;...

...&lt;/p&gt;
&lt;p&gt;The meat of the action takes place in the &lt;strong&gt;onOptionsItemSelected()&lt;/strong&gt; method. Here is where the Toolbar (ActionBar) menu item&apos;s click actions are defined.&lt;/p&gt;
&lt;p&gt;public boolean onOptionsItemSelected(MenuItem item) {&lt;/p&gt;
&lt;p&gt;switch (item.getItemId()) {
case R.id.action_clip:
// handle animation here
return true;&lt;br /&gt;
}&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; return super.onOptionsItemSelected(item);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h4&gt;Animation Prerequisites&lt;/h4&gt;
&lt;p&gt;To perform the animation, two parameters are needed:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;X, Y coordinates to start the animation from&lt;/li&gt;
&lt;li&gt;Radius of the circular reveal&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;WhatsApp performs the Reveal effect from the top right.&lt;/p&gt;
&lt;p&gt;int cx = (mRevealView.getLeft() + mRevealView.getRight());
int cy = mRevealView.getTop();&lt;/p&gt;
&lt;p&gt;If you need it from the center, then just change &lt;strong&gt;cy&lt;/strong&gt; to this instead:  &lt;code&gt;int cy = (mRevealView.getTop() + mRevealView.getBottom())/2;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The radius can be obtained using this method:&lt;/p&gt;
&lt;p&gt;int radius = Math.max(mRevealView.getWidth(), mRevealView.getHeight());&lt;/p&gt;
&lt;h4&gt;ViewAnimationUtils&lt;/h4&gt;
&lt;p&gt;Now we can finally initiate the reveal effect.&lt;/p&gt;
&lt;p&gt;SupportAnimator animator =
ViewAnimationUtils.createCircularReveal(mRevealView, cx, cy, 0, radius);
animator.setInterpolator(new AccelerateDecelerateInterpolator());
animator.setDuration(400);&lt;/p&gt;
&lt;p&gt;SupportAnimator animator_reverse = animator.reverse();&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Be very careful of the imports here. &lt;strong&gt;ViewAnimationUtils&lt;/strong&gt; is imported from from the external library, and NOT the default android.view.ViewAnimationUtils import.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;animator&lt;/strong&gt; will be used for revealing the view on tap, while &lt;strong&gt;animator_reverse&lt;/strong&gt; in essense reverses the animation for hiding back the view when tapped again.&lt;/p&gt;
&lt;h4&gt;Animation Toggle&lt;/h4&gt;
&lt;p&gt;We will use a simple boolean &lt;strong&gt;hidden&lt;/strong&gt;  to handle the toggling.&lt;/p&gt;
&lt;p&gt;if (hidden) {
mRevealView.setVisibility(View.VISIBLE);
animator.start();
hidden = false;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;          } else {

              animator_reverse.addListener(new SupportAnimator.AnimatorListener() {
              
                  @Override
                  public void onAnimationEnd() {
                      mRevealView.setVisibility(View.INVISIBLE);
                      hidden = true;
                  }
                  ...
              });

              animator_reverse.start();
          }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that we need to make the view visible before we being the reveal effect. While this simply works, its not the same for the reverse effect. The library&apos;s &lt;strong&gt;SupportAnimator&lt;/strong&gt; provides a method &lt;strong&gt;reverse()&lt;/strong&gt; to reverse the animation. We cannot just set the view invisible before starting the animation. The animation performed will never be visible.&lt;/p&gt;
&lt;p&gt;For this we will use the &lt;strong&gt;AnimatorListener&lt;/strong&gt;. Once the reverse animation ends, the convenient &lt;strong&gt;onAnimationEnd()&lt;/strong&gt; method will allow us to hide the view.&lt;/p&gt;
&lt;p&gt;Be sure to update the boolean &lt;strong&gt;hidden&lt;/strong&gt; accordingly in the if and else cases.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Lollipop Fix&lt;/h3&gt;
&lt;p&gt;Strangely, this doesn&apos;t seem to work on Lollipop 5.0.1 and above. As in, the transition itself doesn&apos;t work. A simple workaround for this would be to use Android&apos;s native ViewAnimationUtils for devices Lollipop and above.&lt;/p&gt;
&lt;p&gt;Simply wrap the code you just wrote like this.&lt;/p&gt;
&lt;p&gt;if (Build.VERSION.SDK_INT &amp;lt; Build.VERSION_CODES.LOLLIPOP) {
// Your previously written code
} else {
// Same code here but import ViewAnimationUtils from android.view.ViewAnimationUtils
Animator anim = android.view.ViewAnimationUtils.createCircularReveal(mRevealView, cx, cy, 0, radius);
...
}&lt;/p&gt;
&lt;p&gt;Hope the comments there were self explanatory. There&apos;s no need for the support animator as well. You can look at my code &lt;a href=&quot;https://github.com/Suleiman19/Android-Material-Design-for-pre-Lollipop/blob/master/MaterialSample/app/src/main/java/com/suleiman/material/activities/RevealAnimation.java&quot;&gt;here&lt;/a&gt;, just in case.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;That&apos;s it. While this post, for the most part was just my explaining, the actual implementation itself is pretty simply and straightforward once you do it yourself. The &lt;a href=&quot;https://github.com/ozodrukh/CircularReveal&quot;&gt;Circular Reveal library by ozodrukh&lt;/a&gt; is brilliant and works nicely.&lt;/p&gt;
&lt;p&gt;Here&apos;s the final output and it looks amazing.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/circular-reveal-effect-like-whatsapp-in-android/reveal-effect-final.gif&quot; alt=&quot;reveal-effect-final&quot; /&gt;&lt;/p&gt;
&lt;p&gt;As always, here&apos;s the link to my &lt;a href=&quot;https://github.com/Suleiman19/Android-Material-Design-for-pre-Lollipop/blob/master/MaterialSample/app/src/main/java/com/suleiman/material/activities/RevealAnimation.java&quot;&gt;Git&lt;/a&gt; for code reference.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./circular-reveal-effect-like-whatsapp-in-android/49596856.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;You can get creative with which views your using, be it a simple view or an entire screen transition itself! I simply used WhatsApp&apos;s Attach button as an example.&lt;/p&gt;
&lt;p&gt;Show me what you can come up with and drop em in the comments below.&lt;/p&gt;
</content:encoded></item><item><title>Design App Mockups with Adobe Illustrator &amp; InVision</title><link>https://blog.iamsuleiman.com/how-to-design-app-mockups-like-a-pro/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/how-to-design-app-mockups-like-a-pro/</guid><description>Designing app mockups allow us to quickly visualize how our app might ultimately look like. In this article tutorial, let&apos;s learn how to do this reall</description><pubDate>Wed, 08 Jul 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Designing app mockups allow us to quickly visualize how our app might ultimately look like. In this article tutorial, let&apos;s learn how to do this really quick with Adobe Illustrator and InVision. I will also tell you the benefits of doing this and guide you every step of the way. While I say this blog is about Android app development and design, my series of recent posts were hardly anything about the latter. Adobe Illustrator along with InVision are two powerful tools when used together. Before we jump ahead to the softwares, let&apos;s discuss about why we need app mockups in the first place?&lt;/p&gt;
&lt;h2&gt;Why Design App Mockups?&lt;/h2&gt;
&lt;p&gt;To develop any app, what is required first is a visual idea of the end product. A mockup. Note that although this article talks about app mockups. You could do static mockups for any digital product/software. So why do a mockup when you could spend that time building the actual thing? Good question.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A &lt;strong&gt;mockup,&lt;/strong&gt; is a model of a design, used for demonstration and design evaluation. It is used by designers mainly to acquire feedback from users. Mock-ups address the idea captured in a popular engineering one-liner: &lt;strong&gt;You can fix it now on the drafting board with an eraser or you can fix it later on the construction site with a sledge hammer&lt;/strong&gt;. - &lt;a href=&quot;https://en.wikipedia.org/wiki/Mockup&quot;&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Note the last line quoted above. It implies that making corrections early on is easier and less costly, rather than having to rework on your actual designs later on into development. Long story short, you save time and frustration, if you pay attention to things now. Also, if you didn&apos;t understand any of that, a mockup is simply a static image design of what an app screen will exactly look like. Here&apos;s an example of a app mockup that I made.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./how-to-design-app-mockups-like-a-pro/dailyui_023_onboarding.png&quot; alt=&quot;&quot; title=&quot;Onboarding App Mockup - Dribbble&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Getting to know the tools&lt;/h3&gt;
&lt;p&gt;Now that we&apos;re clear on what an app mockup actually is, let&apos;s look at the tools we need. As I&apos;ve previously mentioned above, the two software that we&apos;re going to use are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Adobe Illustrator&lt;/li&gt;
&lt;li&gt;InVision App&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;Adobe Illustrator&lt;/h4&gt;
&lt;blockquote&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./how-to-design-app-mockups-like-a-pro/adobe_illustrator_cc_logo.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;A professional software for graphic design. It specializes in &lt;a href=&quot;https://vectr.com/tutorials/what-are-vector-graphics/&quot;&gt;Vector Graphics&lt;/a&gt; and is the industry standard.&lt;/p&gt;
&lt;p&gt;If you don&apos;t have the software, you can grab a free-trial of &lt;a href=&quot;https://www.adobe.com/products/illustrator.html#idccPlansModal&quot;&gt;Adobe Illustrator CC 2018&lt;/a&gt;. &lt;em&gt;Yeah, I know that today there&apos;s a better tool out there *cough*  Sketch *cough* that&apos;s more well-suited (and fancy). Maybe I&apos;ll cover that in another tutorial, but for now, let&apos;s focus on Illustrator.&lt;/em&gt; Once you have Illustrator set up, keep in mind that it is a fairly complex software. But I will show you how to use it easily and design app mockups fast! Just to note, you do not require extensive knowledge of Illustrator. But I do recommend a getting started video at the LEAST just to familiarize yourself with the workflow. However, not to be alarmed as we&apos;ll just be doing simple drag and drop. If you&apos;re interested in learning Adobe Illustrator, I&apos;d suggest you check out &lt;a href=&quot;https://www.udemy.com/adobe-illustrator-training/&quot;&gt;this course by Udemy&lt;/a&gt;. It provides free Adobe Illustrator classes.&lt;/p&gt;
&lt;h5&gt;UI Kits to design app mockups, faster&lt;/h5&gt;
&lt;p&gt;There are many available resources to accelerate our workflow such as UI kits specifically for mobile, be it Android or iOS. I&apos;ll be using a free UI Kit for &lt;a href=&quot;https://material.io/&quot;&gt;Google Material Design&lt;/a&gt;. I strongly suggest you use one so you can simply drag and drop UI components instead of designing them from scratch. &lt;em&gt;Grab the UI kit &lt;a href=&quot;http://goo.gl/g0g5Xo&quot;&gt;here&lt;/a&gt;.&lt;/em&gt; &lt;strong&gt;Exploring the Material Design UI Kit&lt;/strong&gt; Once you&apos;ve downloaded the UI kit, let&apos;s take a look at what it has to offer. Inside the &lt;a href=&quot;http://goo.gl/g0g5Xo&quot;&gt;UI kit&lt;/a&gt; you downloaded, there will be 3 files under the &apos;&lt;em&gt;master&lt;/em&gt;&apos; folder:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;the actual kit&lt;/li&gt;
&lt;li&gt;the individual UI elements&lt;/li&gt;
&lt;li&gt;Typography styles&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can notice the UI kit is quite exhaustive, and that&apos;s only half of what I could screenshot. As a bonus, the &apos;resources&apos; folder also includes the entire &apos;Roboto&apos; font and the complete Material Design color palette. Neat!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./how-to-design-app-mockups-like-a-pro/ui-kit-spread-1200x656.png&quot; alt=&quot;ui kit spread&quot; /&gt;&lt;/p&gt;
&lt;h5&gt;InVision &lt;strong&gt;App&lt;/strong&gt;&lt;/h5&gt;
&lt;blockquote&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./how-to-design-app-mockups-like-a-pro/invision-logo-png-transparent.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;A prototyping tool that helps you put your designs together and add interactivity to it. It helps you understand how your products will behave and also serves as a deliverable to developers.&lt;/p&gt;
&lt;p&gt;InVision is free to start so go ahead and &lt;a href=&quot;https://www.invisionapp.com/&quot;&gt;sign up&lt;/a&gt;! We will be using &lt;a href=&quot;http://www.invisionapp.com/&quot;&gt;InVision&lt;/a&gt; to finally put together our mockups and bring our prototype to life. But more on that later.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Designing App Mockups with Adobe Illustrator&lt;/h3&gt;
&lt;p&gt;I will suggest using Adobe Illustrator for mockups. Now many of you may say why not Adobe Photoshop, but &lt;a href=&quot;https://www.designernews.co/stories/2525-illustrator-for-ui-design&quot;&gt;read this discussion on DesignerNews&lt;/a&gt; as to why Illustrator is better suited for UI design. Now, let&apos;s get down to actually designing our app mockup screens.&lt;/p&gt;
&lt;h4&gt;Document &amp;amp; Grid Setup&lt;/h4&gt;
&lt;p&gt;Start by creating a New Document in Adobe Illustrator. We won&apos;t be going with a preset but rather creating one of our own. So use the following settings to create a new document.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Width: 360 px&lt;/li&gt;
&lt;li&gt;Height: 640 px&lt;/li&gt;
&lt;li&gt;Advanced&amp;gt; Raster Effects: Screen (72 ppi)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./how-to-design-app-mockups-like-a-pro/illustrator_artboard_settings.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now we&apos;ll setup a grid for our work, so our elements can align perfectly. Go to &lt;strong&gt;Edit &amp;gt; Preferences &amp;gt; Guides &amp;amp; Grid&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gridline every: 64 px&lt;/li&gt;
&lt;li&gt;Subdivisions: 8&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./how-to-design-app-mockups-like-a-pro/grid-setup-420x293.png&quot; alt=&quot;grid setup&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Don&apos;t fret seeing this as a troublesome process. You can save this as a template so you can jump start your work from the next time.&lt;/p&gt;
&lt;h5&gt;Process&lt;/h5&gt;
&lt;p&gt;Create two new &lt;a href=&quot;https://theblog.adobe.com/save-time-global-color-swatches/&quot;&gt;Global Color Swatches&lt;/a&gt; in your color palette, one named &apos;&lt;em&gt;primary&lt;/em&gt;&apos; and the other &apos;&lt;em&gt;accent&lt;/em&gt;&apos;. Those familiar with &lt;a href=&quot;https://material.io/design/color/the-color-system.html&quot;&gt;how color works in Material Design&lt;/a&gt; should instantly be able to recognize what I just did there. As the name goes, those two are primary and accent colors that will be global to our app design. In other words, those are our brand colors. One primary and one secondary. We do this so that we can swap out the default colors with our brand colors in the Material Design UI kit. &lt;strong&gt;Helpful Reading:&lt;/strong&gt; &lt;a href=&quot;https://www.jenreviews.com/color-meaning/&quot;&gt;Color Psychology - What do different colors mean?&lt;/a&gt; Now open the UI Kit files that you just downloaded. Drag and drop whatever components you need to swiftly build your app mockups. The beauty here is, when you drag and drop the desired elements onto your Artboard, you will be asked whether to &apos;&lt;strong&gt;Merge Swatches&lt;/strong&gt;&apos;. Hit that option and watch as the objects take on your document&apos;s primary and accent colors. Great!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./how-to-design-app-mockups-like-a-pro/illustrator_global_color_swatches.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;From now on the process is the same, rinse and repeat. Drag your required elements from your UI kit over to your document&lt;/p&gt;
&lt;h5&gt;Metrics&lt;/h5&gt;
&lt;p&gt;The width of each grid column is &lt;strong&gt;8px&lt;/strong&gt;. This is the baseline grid used in &lt;a href=&quot;https://material.io/design/layout/spacing-methods.html#baseline&quot;&gt;Material Design metrics for design&lt;/a&gt;. So if you plan on making a FAB (&lt;a href=&quot;https://www.google.co.in/design/spec/components/buttons-floating-action-button.html&quot;&gt;Floating Action Button&lt;/a&gt;- see below), that would be &lt;strong&gt;56 px&lt;/strong&gt; (8 x 7 ). While the guidelines mention in &lt;strong&gt;dp&lt;/strong&gt; (for apps), you can continue to use &lt;strong&gt;px&lt;/strong&gt; in your designs. So if you see, the grid helps us scale well. The UI kit would have elements in the right dimensions anyway.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./how-to-design-app-mockups-like-a-pro/metrics.png&quot; alt=&quot;metrics&quot; title=&quot;Floating Action Button adhering to an 8-point baseline grid&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Final Results - Output&lt;/h3&gt;
&lt;p&gt;Now once you&apos;re done with your screens, save them via &lt;strong&gt;File &amp;gt; Save for Web.&lt;/strong&gt; Now its called &apos;Save for Web&apos; for a reason so I strongly suggest you use this option. You can save as either a JPEG or PNG. Deliberately save at medium quality so your mockups will load fast on a browser. Alternately  you can scale it at a decent 1280x720 and save but I&apos;d caution against pushing further than that.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./how-to-design-app-mockups-like-a-pro/mock-list.jpg&quot; alt=&quot;Mockup: contact list screen&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./how-to-design-app-mockups-like-a-pro/mockup-contact.jpg&quot; alt=&quot;Mockup: contact detail screen&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./how-to-design-app-mockups-like-a-pro/mock-calling.jpg&quot; alt=&quot;Mockup: calling screen&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;App Structure&lt;/h4&gt;
&lt;p&gt;Now that we have all our screens together, the purpose of a mockup is to mimic a &apos;feel&apos; of the end product. I know its not the real thing, but it should be close enough. So to mimic that realism we need to have a screen flow to logically show how our app will behave and navigate upon certain action. Now keep in mind that being a mockup, focus on the primary actions first. So for my caller app, I&apos;m going to focus on this simple screen flow. Home screen (Contact List) -&amp;gt; Contact profile screen -&amp;gt; Calling screen Yes, I know an app consists of more, but this is just a demo and if you see, I&apos;ve already covered the prime aspects. We don&apos;t care about a settings page right now. The purpose of my calling app is to view my contacts, view details about a specific contact and finally be able to call that contact.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;You might want to take a breather here. We&apos;re only half way through ;-)&lt;/em&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;Buy the Book&lt;/em&gt;   Anyone can design a user interface, but if you&apos;re interested in designing one that is effective and converts your users better, I suggest you read &apos;&lt;a href=&quot;http://www.amazon.com/gp/product/0123969808/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0123969808&amp;amp;linkCode=as2&amp;amp;tag=graartblo-20&amp;amp;linkId=IN5C7W23WBVY6L6O&quot;&gt;UI is Communication - Everett N McKay&lt;/a&gt;&apos;. A brilliant book that teaches how to communicate with your users, through your UI.&lt;/p&gt;
&lt;h2&gt;Putting it together with InVision&lt;/h2&gt;
&lt;p&gt;To do what I&apos;ve mentioned above, we&apos;ll use a web app called InVision. I happened to take part in a Startup Weekend challenge last year where I happened to learn about this beauty.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./how-to-design-app-mockups-like-a-pro/invision-site-1200x684.png&quot; alt=&quot;invision site&quot; /&gt;&lt;/p&gt;
&lt;p&gt;InVision an online tool that allows us to put together our screens, define clickable regions that navigate to other screens. It helps sculpt our app navigation flow. As a bonus we got animation on click effects and they even wrap our designs neatly in a phone so when we look at it, its like looking at the real thing! Now InVision has a pricing plan, but upto one project it is free. I find this fair enough, because unlike other prototyping tools I&apos;ve used, most of my time is spent up in trying to learn the tool or worrying about limitations on the free version. At least I don&apos;t have to bother about that with InVision. I can simply design my screens using any of my favorite graphic software, then upload to InVision and arrange them. Simple and intuitive.&lt;/p&gt;
&lt;h3&gt;How it Works&lt;/h3&gt;
&lt;p&gt;Start by signing into InVision (or creating an account). I&apos;m actually surprised as how much InVision has changed over the year. They support Dropbox and Drive, even let you upload various image formats, including direct PSD files. But I am using JPG.&lt;/p&gt;
&lt;h3&gt;Setup&lt;/h3&gt;
&lt;p&gt;Create a new project for Android Phone in Portrait. Then add in all your screens. Just make sure their named well enough for you to identify (if you&apos;re handling many). The dashboard might take a little time getting used to, but trust me its easy. Simply tap the screen you want to start with and you&apos;re off. Start by going to &lt;strong&gt;Build Mode(B)&lt;/strong&gt;.Here&apos;s where most of work will happen. From now on, what we&apos;ll be doing is three steps repeatedly.&lt;/p&gt;
&lt;h3&gt;The 3 Step Process:&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;./how-to-design-app-mockups-like-a-pro/invision-in-action-1200x684.png&quot; alt=&quot;invision in action&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Define your clickable regions (Hotspots)&lt;/li&gt;
&lt;li&gt;Select a destination screen&lt;/li&gt;
&lt;li&gt;Choose a transition effect to go with it&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That&apos;s all there is to it! Rinse repeat these 3 steps for all your screen controls. Don&apos;t forget to include back navigation at the bottom. Selecting a transition will add a more realistic feel for the app. Also note that you can optionally chose a different gesture apart from a tap, which includes swiping, double taps and more.&lt;/p&gt;
&lt;h2&gt;Final Mockup&lt;/h2&gt;
&lt;p&gt;So here it is! The final app mockup. Personally to me, it looks great. I&apos;ve wrapped it in a white Galaxy S4, hidden the status bar as well (accessible via the gear icon below), and the app navigates as it should. &lt;a href=&quot;https://youtu.be/cB2109NPWgY&quot;&gt;Watch on YouTube&lt;/a&gt; Now I don&apos;t know who you are Trevor, but thank you for gracing my design.&lt;/p&gt;
&lt;h2&gt;Advantages&lt;/h2&gt;
&lt;p&gt;Now that we&apos;re done. Let me tell you WHY I chose to do my mockups this way. Well, I can use a software of my choice for design, one that I&apos;m comfortable with. I&apos;m able to design faster as a result of that. InVision is a powerful tool because it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;can sync from the cloud&lt;/li&gt;
&lt;li&gt;accepts various image formats (PSD &amp;amp;  Sketch too!)&lt;/li&gt;
&lt;li&gt;can collaborate with other teammates&lt;/li&gt;
&lt;li&gt;can help receive real-time feedback on designs&lt;/li&gt;
&lt;li&gt;has a intuitive preview tool that looks great&lt;/li&gt;
&lt;li&gt;can be shared with others via a simple link&lt;/li&gt;
&lt;li&gt;can view design on an actual smartphone (via link)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./how-to-design-app-mockups-like-a-pro/image.png&quot; alt=&quot;doge meme&quot; /&gt; *&lt;/p&gt;
&lt;p&gt;Finally we&apos;re done with this long post. I see design as creative work that must be enjoyed. We&apos;ve been introduced to two great tools: Illustrator and InVision, which help us create designs with great flexibility and put them together as a working prototype respectively. With InVision you can take it a step further, update your designs on the fly, add team members to collaborate as well. Both are powerful tools to help ease your design process. So if you&apos;re still struggling in code for initial design showcases, ditch that and get started here!&lt;/p&gt;
</content:encoded></item><item><title>Material Design Android Ripple Effect</title><link>https://blog.iamsuleiman.com/android-ripple-effect/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/android-ripple-effect/</guid><description>Here&apos;s on how to add a neat Ripple effect for your UI components. I&apos;ll take a button for this. Create new folder _res/drawable-v21_ and create a new X</description><pubDate>Wed, 01 Jul 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Here&apos;s on how to add a neat Ripple effect for your UI components. I&apos;ll take a button for this. Create new folder &lt;em&gt;res/&lt;strong&gt;drawable-v21&lt;/strong&gt;&lt;/em&gt; and create a new XML &lt;strong&gt;ripple.xml&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Add this to your button layout:  &lt;code&gt;android:background=&quot;@drawable/ripple&quot;&lt;/code&gt; Note that the Android ripple effect only works on Lollipop versions and above. So you might want to use a normal color selector for previous versions as a fallback. So set your background to be a regular color selector, and for Lollipop handle it like this in your Activity.java&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (Build.VERSION.SDK_INT &amp;gt;= Build.VERSION_CODES.LOLLIPOP) {
             button.setBackground(getDrawable(R.drawable.ripple));
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Integrate Facebook Login with Parse - Part 2</title><link>https://blog.iamsuleiman.com/facebook-login-with-parse-part-2/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/facebook-login-with-parse-part-2/</guid><description>If you&apos;ve managed to survive Part 1(https://blog.iamsuleiman.com/facebook-login-with-parse-part-1/), then welcome to Part 2 of the post! Here we&apos;ll lo</description><pubDate>Sat, 27 Jun 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you&apos;ve managed to survive &lt;a href=&quot;https://blog.iamsuleiman.com/facebook-login-with-parse-part-1/&quot;&gt;Part 1&lt;/a&gt;, then welcome to Part 2 of the post! Here we&apos;ll look at actually integrating Facebook login with Parse. We&apos;ll fetch needed details from Facebook, sign up the user with Parse and store those details. In the previous part, we focused solely on getting Parse and Facebook SDK integrated in our apps, which by in itself was no ordinary feat. Now let&apos;s dive into our app and get these things to work.&lt;/p&gt;
&lt;h2&gt;Why Social Sign In?&lt;/h2&gt;
&lt;p&gt;The very fact that why we opt for a social login is to provide a richer login experience. The user already has his registered credentials on Facebook. We can use that do validate an existing user, rather than asking him to manually fill input fields. This is tedious on the user&apos;s part, which can be avoided. Moreover we can optionally pull other relevant data, which we can utilize to provide a richer user experience.&lt;/p&gt;
&lt;h2&gt;Create a Login Experience&lt;/h2&gt;
&lt;p&gt;The reason why I&apos;ve purposely labelled it a login &apos;experience&apos; which in short is your login screen, is because this is where users get to see your app for the first time, and if they don&apos;t like it now, they&apos;re probably never going to return. This is the very first screen your user will see and I strongly you spend ample time creating a good signup screen. Here&apos;s mine:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./facebook-login-with-parse-part-2/parse-app-layout.png&quot; alt=&quot;parse-app-layout&quot; /&gt;&lt;/p&gt;
&lt;p&gt;But for practice purposes, just a button would do for now. This button on click, will log in the user via Facebook.&lt;/p&gt;
&lt;h2&gt;Facebook Login&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;mBtnFb.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
         ParseFacebookUtils.logInWithReadPermissionsInBackground(MainActivity.this, mPermissions, new LogInCallback() {
                   @Override
                   public void done(ParseUser user, ParseException err) {

                       if (user == null) {
                           Log.d(&quot;MyApp&quot;, &quot;Uh oh. The user cancelled the Facebook login.&quot;);
                       } else if (user.isNew()) {
                           Log.d(&quot;MyApp&quot;, &quot;User signed up and logged in through Facebook!&quot;);
                           getUserDetailsFromFB();
                       } else {
                           Log.d(&quot;MyApp&quot;, &quot;User logged in through Facebook!&quot;);
                           getUserDetailsFromParse();
                       }
                   }
               });
           }
       });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;strong&gt;logInWithReadPermissionsInBackground&lt;/strong&gt; is what we&apos;ll use to log in the user. We must supply a list of permissions to this method. This is akin to an AsyncTask. The &lt;strong&gt;LogInCallback&lt;/strong&gt; provides a &lt;strong&gt;done()&lt;/strong&gt; method. This is essentially what you must do upon log in completion. The 3 if conditions are clearly denoted by their respective Log tags. Upon logging in for the very first time, the app will redirect you to a Facebook screen where he/ she must consent that your app requires their Facebook information. After this we&apos;re back to our app. So now, you might want to take the user to your home screen with a successful Toast message! Alternatively, if it get&apos;s cancelled you should handle the error.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;New Users&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;user.isNew()&lt;/code&gt; helps us identify that a new user is signing up. So after they log in via Facebook, we will retrieve their profile photo, name and email from Facebook. Then we will save those details to Parse. The &lt;strong&gt;getUserDetailsFromFB()&lt;/strong&gt; method will help in fetching our Facebook data.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private void getUserDetailsFromFB() {

     // Suggested by https://disqus.com/by/dominiquecanlas/
     Bundle parameters = new Bundle();
     parameters.putString(&quot;fields&quot;, &quot;email,name,picture&quot;);

     new GraphRequest(
             AccessToken.getCurrentAccessToken(),
             &quot;/me&quot;,
             parameters,
             HttpMethod.GET,
             new GraphRequest.Callback() {
                 public void onCompleted(GraphResponse response) {
         /* handle the result */
                     try {

                         email = response.getJSONObject().getString(&quot;email&quot;);
                         mEmailID.setText(email);

                         name = response.getJSONObject().getString(&quot;name&quot;);
                         mUsername.setText(name);

                         JSONObject picture = response.getJSONObject().getJSONObject(&quot;picture&quot;);
                         JSONObject data = picture.getJSONObject(&quot;data&quot;);

                         //  Returns a 50x50 profile picture
                         String pictureUrl = data.getString(&quot;url&quot;);

                         new ProfilePhotoAsync(pictureUrl).execute();

                     } catch (JSONException e) {
                         e.printStackTrace();
                     }
                 }
             }
     ).executeAsync();

 }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, in essence this method will be responsible for executing 2 AsyncTasks:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;GraphRequest&lt;/em&gt; - to fetch user name and email&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;a href=&quot;http://developer.android.com/reference/android/os/AsyncTask.html&quot;&gt;AsyncTask&lt;/a&gt; (native)&lt;/em&gt; - to download profile photo and display on ImageView&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The &lt;a href=&quot;https://developers.facebook.com/docs/reference/android/current/class/GraphRequest/&quot;&gt;GraphRequest&lt;/a&gt; can help us fetch all sorts of data from Facebook. It requires some time understanding how it works, so I suggest you go through. The GraphResponse returns back &lt;a href=&quot;https://www.w3schools.com/js/js_json_intro.asp&quot;&gt;JSON&lt;/a&gt; data which we can use to retrieve our required information. If you&apos;re unfamiliar with JSON parsing and how it works on Android, you can follow this brilliant post on &lt;a href=&quot;http://www.androidhive.info/2012/01/android-json-parsing-tutorial/&quot;&gt;AndroidHive&lt;/a&gt; that explains it brilliantly. However, that&apos;s only if you&apos;re interested in learning more. For the purposes of this post, you can just copy over my code snippet and it will work just fine :-)&lt;/p&gt;
&lt;h3&gt;saveNewUser()&lt;/h3&gt;
&lt;p&gt;If you noticed carefully, we call this method in the &lt;strong&gt;onCompleted()&lt;/strong&gt; method of our GraphRequest. Why because, this method indicates what must be done upon completing the fetch request. This means that the requested data has been fetched. So once that is done, we can safely store our data in Parse. Doing so before might result in a crash! Alternatively, see the AsyncTask where we download our profile photo. If this takes longer to execute, then our &lt;strong&gt;saveNewUser()&lt;/strong&gt; will still fail. Know why? We&apos;re attempting to download the photo while the AsyncTask may still be executing. If your AsyncTask takes a while, then again the app would crash. I have purposely done it this way to highlight the various issues when tasks execute in parallel. The fail safe way would be to call &lt;strong&gt;saveNewUser()&lt;/strong&gt; in your AsyncTask&apos;s &lt;strong&gt;onPostExecute()&lt;/strong&gt; method.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  private void saveNewUser() {
        parseUser = ParseUser.getCurrentUser();
        parseUser.setUsername(name);
        parseUser.setEmail(email);

//        Saving profile photo as a ParseFile
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        Bitmap bitmap = ((BitmapDrawable) mProfileImage.getDrawable()).getBitmap();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 70, stream);
        byte[] data = stream.toByteArray();
        String thumbName = parseUser.getUsername().replaceAll(&quot;\\s+&quot;, &quot;&quot;);
        final ParseFile parseFile = new ParseFile(thumbName + &quot;_thumb.jpg&quot;, data);

        parseFile.saveInBackground(new SaveCallback() {
            @Override
            public void done(ParseException e) {
                parseUser.put(&quot;profileThumb&quot;, parseFile);

                //Finally save all the user details
                parseUser.saveInBackground(new SaveCallback() {
                    @Override
                    public void done(ParseException e) {
                        Toast.makeText(MainActivity.this, &quot;New user:&quot; + name + &quot; Signed up&quot;, Toast.LENGTH_SHORT).show();
                    }
                });

            }
        });

    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;saveInBackground()&lt;/strong&gt;, evident by the method (Yep you guessed it!) is used to save our user details to Parse via an AsyncTask. You can optionally have a SaveCallback if you want to do anything after a successful save. I&apos;ve just showed a simple Toast notifying the user he signed up. The &lt;a href=&quot;https://parse.com/docs/android/api/com/parse/ParseUser.html&quot;&gt;ParseUser&lt;/a&gt; class is used to fetch information from Parse related to the user, which we have defined globally and initialize only when needed. We set our user&apos;s email and username from what we retrieved from Facebook. Then we save our downloaded Facebook profile photo Bitmap as a &lt;a href=&quot;https://parse.com/docs/android/api/com/parse/ParseFile.html&quot;&gt;ParseFile&lt;/a&gt;. Note how I&apos;m saving this file. I dynamically create the thumbnail&apos;s file name based off the username. &apos;profileThumb&apos; is a column which will automatically be created in our User class if it doesn&apos;t exist.&lt;/p&gt;
&lt;h3&gt;Profile Photo AsyncTask&lt;/h3&gt;
&lt;p&gt;Create a new class called ProfilePhotoAsync and make it extend &lt;a href=&quot;http://developer.android.com/reference/android/os/AsyncTask.html&quot;&gt;AsyncTask&lt;/a&gt;. Now I&apos;m not going too in depth about what these are for the post&apos;s sake.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In short, any task that will take time to execute or its duration to finish is unknown. If it risks stalling the UI making the app non responsive, then AsyncTask is your solution. This is exactly what we&apos;ll use to download our profile photo from Facebook.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class ProfilePhotoAsync extends AsyncTask {
      public Bitmap bitmap;
      String url;

      public ProfilePhotoAsync(String url) {
          this.url = url;
      }

      @Override
      protected String doInBackground(String... params) {
          // Fetching data from URI and storing in bitmap
          bitmap = DownloadImageBitmap(url);
          return null;
      }

      @Override
      protected void onPostExecute(String s) {
          super.onPostExecute(s);
          mProfileImage.setImageBitmap(bitmap);

          saveNewUser();
      }
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The brunt of your work must be done in the &lt;strong&gt;doneInBackground()&lt;/strong&gt; method, which is why we&apos;re handling the actual download there. After your task is complete, what is be done next must come in the &lt;strong&gt;onPostExecute()&lt;/strong&gt; method. When this method enters, our download task would be complete. So now we can set our downloading bitmap to our ImageView.&lt;/p&gt;
&lt;h4&gt;DownloadImageBitmap()&lt;/h4&gt;
&lt;p&gt;We&apos;ll use this handy utility method to handle our download. We simply pass a URL as a parameter to this method, which will return a Bitmap at the end. &lt;strong&gt;NOTE:&lt;/strong&gt; Network operations must be run off the UI thread!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static Bitmap DownloadImageBitmap(String url) {
        Bitmap bm = null;
        try {
            URL aURL = new URL(url);
            URLConnection conn = aURL.openConnection();
            conn.connect();
            InputStream is = conn.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(is);
            bm = BitmapFactory.decodeStream(bis);
            bis.close();
            is.close();
        } catch (IOException e) {
            Log.e(&quot;IMAGE&quot;, &quot;Error getting bitmap&quot;, e);
        }
        return bm;
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;p&gt;Whoa! That was really long. Let&apos;s take a breather here and look at what we&apos;ve done so far. Up till now we&apos;ve seen how to handle a NEW user. Fetched relevant details and photo from Facebook and saved it to Parse. Just make sure you&apos;re testing this app on a REAL device so we have internet and Facebook to work with. &lt;a href=&quot;http://www.amazon.com/gp/product/B00GDBN6KQ/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=B00GDBN6KQ&amp;amp;linkCode=as2&amp;amp;tag=graartblo-20&amp;amp;linkId=XCQYDUUJBYMVMNPM&quot;&gt;LG Nexus 5&lt;/a&gt; is said to be the best device for this by many. Do run the app just ONCE. Log in and you will get a Toast saying you signed up. Great! Back to the post. We&apos;ll now show a Welcome back Toast if its a returning user that logs in. This is what your Parse panel should show you, after successfully running it once. There is now one new entry in your User class. Note all the relevant details from your Facebook fed into your Parse backend.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./facebook-login-with-parse-part-2/parse-data-entry-744x100.png&quot; alt=&quot;parse-data-entry&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Returning User&lt;/h2&gt;
&lt;p&gt;We will simply fetch 3 data from Parse: name, email and profile photo (which we saved to a ParseFile).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; private void getUserDetailsFromParse() {
        parseUser = ParseUser.getCurrentUser();

//Fetch profile photo
        try {
            ParseFile parseFile = parseUser.getParseFile(&quot;profileThumb&quot;);
            byte[] data = parseFile.getData();
            Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
            mProfileImage.setImageBitmap(bitmap);
        } catch (Exception e) {
            e.printStackTrace();
        }

        mEmailID.setText(parseUser.getEmail());
        mUsername.setText(parseUser.getUsername());

        Toast.makeText(MainActivity.this, &quot;Welcome back &quot; + mUsername.getText().toString(), Toast.LENGTH_SHORT).show();

    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The email and username is fetched after initializing &lt;strong&gt;ParseUser&lt;/strong&gt; and directly passed on to our TextViews. The &lt;strong&gt;ParseFile&lt;/strong&gt; is retrieved  via parseUser by specifying the &apos;key&apos; (column name in the table). However, simply retrieving the file will not suffice so we basically have to undo the file conversion steps we did while storing the Bitmap into a ParseFile. Here, we have to reconstruct the Bitmap from the ParseFile data. Finally after all that, display a Toast welcoming back the user! Finally run the app now (second time) and log in via Facebook. You will see our name, email and profile photo appearing. Nothing new same as last time, but as developers, we know that only this time, the data which was earlier saved in Parse, is now being retrieved. :-)&lt;/p&gt;
&lt;h2&gt;End Result&lt;/h2&gt;
&lt;p&gt;I know the post has been long without any visual result. But finally here&apos;s an output you all can feast your eyes on!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/facebook-login-with-parse-part-2/Parse-Facebook-login.gif&quot; alt=&quot;Parse Facebook login&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Do ignore the grey rectangle in the middle. That&apos;s just me doing a miserable job of trying to hide my email ;-) Also note that the Facebook confirmation screen for you will look different (better and faster). I&apos;m using an emulator (which sucks). You can also check out this code sample on &lt;a href=&quot;https://github.com/Suleiman19/ParseApp/blob/master/app/src/main/java/com/grafixartist/parseapp/MainActivity.java&quot;&gt;GitHub&lt;/a&gt;. Just be sure to replace your Facebook AppID, Parse Application ID and Client Key in &lt;strong&gt;values/strings.xml&lt;/strong&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Great. Now go ahead and jump in joy as you&apos;re done with this long post. Don&apos;t forget to &lt;a href=&quot;https://twitter.com/Suleiman_194&quot;&gt;Follow @Suleiman_194&lt;/a&gt; and subscribe (below) for instant updates!&lt;/p&gt;
</content:encoded></item><item><title>Integrate Facebook Login with Parse - Part 1</title><link>https://blog.iamsuleiman.com/facebook-login-with-parse-part-1/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/facebook-login-with-parse-part-1/</guid><description>If you&apos;ve heard about Parse back-end, then you&apos;ll also know that its a wonderful service which simplifies back-end management for your Android apps. L</description><pubDate>Thu, 25 Jun 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you&apos;ve heard about Parse back-end, then you&apos;ll also know that its a wonderful service which simplifies back-end management for your Android apps. Let&apos;s look at adding a Facebook login experience using Parse. This is part one of the post where I&apos;ll take time to help you familiarize yourself with these services. Along with integrating Parse, we&apos;ll also look look at adding a Facebook login to our app. For simplicity&apos;s sake, in part one we&apos;ll ONLY be looking at integrating the two. I will be mentioning essentials only, so that you can be swiftly done with a tedious boring process. We will first create a backend server for our app using Parse, upload test data to your backend as a check and then finally add the Facebook SDK and link it to Parse.&lt;/p&gt;
&lt;h2&gt;What is Parse?&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.parse.com/&quot;&gt;Parse&lt;/a&gt; is a Backend as a Service (&lt;a href=&quot;https://en.wikipedia.org/wiki/Mobile_Backend_as_a_service&quot;&gt;BaaS&lt;/a&gt;). It helps maintain a backend for your app, eliminating the need for you to manage a server or get caught in server side code. Parse greatly simplifies this process with &lt;a href=&quot;https://www.parse.com/docs/android/guide&quot;&gt;their Android SDK&lt;/a&gt;. You&apos;ll wonder at just how much you&apos;re able to do with so little code, it&apos;s almost a miracle! Their pricing plans is quite generous as well so its more than enough for our purposes. Even for small realtime apps!&lt;/p&gt;
&lt;h2&gt;&lt;a href=&quot;https://developers.facebook.com/docs/android&quot;&gt;Facebook SDK&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Facebook&apos;s SDK for Android lets us augment our apps with powerful social features. But for now, we&apos;re only interested in their &lt;a href=&quot;https://developers.facebook.com/docs/facebook-login/android/v2.3&quot;&gt;Login feature&lt;/a&gt;. We need to connect Facebook&apos;s SDK to Parse first. Upon doing so, we can handle Facebook login with Parse.&lt;/p&gt;
&lt;h2&gt;Android Studio Setup&lt;/h2&gt;
&lt;p&gt;I&apos;m including my Gradle settings in case any of you should run into issues, you can cross check here first :-)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;compileSdkVersion 23&lt;/li&gt;
&lt;li&gt;buildToolsVersion 23.0.2&lt;/li&gt;
&lt;li&gt;minSdkVersion 15&lt;/li&gt;
&lt;li&gt;targetSdkVersion 23&lt;/li&gt;
&lt;li&gt;support libraries 23.1.1&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Setting up Parse&lt;/h2&gt;
&lt;p&gt;Start off with creating a Parse account (if you don&apos;t have one). You&apos;ll be presented with a welcome screen.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./facebook-login-with-parse-part-1/welcome-to-parse-e1435166346314-744x391.png&quot; alt=&quot;welcome to parse&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;New Project&lt;/h3&gt;
&lt;p&gt;Click Data&amp;gt; Mobile&amp;gt; Android&amp;gt; Native (Java)&amp;gt; Existing Project Now you could go ahead following Parse&apos;s on screen instructions, but I strongly suggest you follow mine instead for a more updated approach. But don&apos;t close that page just yet. Why existing? Because trust me, its better to add Parse manually to our app. On the last step, start off with downloading the latest SDK from there, or &lt;a href=&quot;https://www.parse.com/downloads/android/Parse/latest&quot;&gt;here&lt;/a&gt;. Hate to break it to you, but unlike other libraries that we include via a single line in Gradle, Parse doesn&apos;t give us such a luxury (yet). So we&apos;ll have to download the library and include the .jar manually.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dependencies {
    ...
    compile &apos;com.parse.bolts:bolts-android:1.3.0&apos;
    compile &apos;com.parse:parse-android:1.12.0&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Connect app to Parse&lt;/h3&gt;
&lt;p&gt;With the libraries in place, we need to now add the respective permissions to the Manifest file and initialize Parse with our unique App ID.&lt;/p&gt;
&lt;p&gt;Create a new class &apos;MyApp&apos; extending Application and add this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class MyApp extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        // Enable Local Datastore.
        Parse.enableLocalDatastore(this);
        
        Parse.initialize(this);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you didn&apos;t close your Parse page yet, the last step will conveniently display your &lt;strong&gt;applicationId&lt;/strong&gt; and &lt;strong&gt;clientKey&lt;/strong&gt; you can just copy it over. Head over to your &lt;em&gt;AndroidManifest.xml&lt;/em&gt; and add this directly under your application tag.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; 

        

        

        ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If all goes well, there won&apos;t be any errors being highlighted using the Parse API.&lt;/p&gt;
&lt;h3&gt;Test&lt;/h3&gt;
&lt;p&gt;However, lets not jump to conclusion and just test if our app is really connected. As Parse says, add the following code in your MainActivity.java onCreate method.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ParseObject testObject = new ParseObject(&quot;TestObject&quot;);
testObject.put(&quot;foo&quot;, &quot;bar&quot;);
testObject.saveInBackground();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Run your app once, hit the Test button and all should be well :-) Once you&apos;re through with that, head over to the Dashboard and click your App. Click the Core tab above. You should see the Data with a class &apos;TestObject&apos; and one data entry.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./facebook-login-with-parse-part-1/test-object-e1435217005741.png&quot; alt=&quot;test-object&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Each data you insert is part of a class which you must define. You can see from the above code sample that &quot;foo&quot; is our column name and &quot;bar&quot; is its corresponding data. To retrieve the data you would use &lt;code&gt;testObject.get(&quot;foo&quot;);&lt;/code&gt; Parse has a really good &lt;a href=&quot;https://www.parse.com/docs/android/guide&quot;&gt;documentation&lt;/a&gt; which is a pleasure to read. I highly recommend that you spend some time reading it.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Finally we&apos;ve included the Parse Android SDK, linked our app with Parse and even tried storing test data to confirm that it works. Now we&apos;ll move onto adding the Facebook SDK for the login.&lt;/p&gt;
&lt;h2&gt;Adding Facebook SDK&lt;/h2&gt;
&lt;p&gt;We need to setup Facebook&apos;s SDK to be used with Parse. Head over to &lt;a href=&quot;https://developers.facebook.com/apps&quot;&gt;Facebook&lt;/a&gt; and add a new Android app.  Now you can follow the on screen instructions over at Facebook to integrate but as always, I suggest you follow this post to get the long version short. You might have noticed that when we copied over the Parse.jar, we did so for the FacebookUtils.jar as well. This is what that&apos;s going to help us link Facebook so Parse can handle the login for us. Add this line to your Gradle to include the Facebook SDK in your app:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;compile &apos;com.facebook.android:facebook-android-sdk:4.7.0&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Do try to follow closely from this point on, otherwise the SDK won&apos;t work. You could have a coffee, relax and get back!&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Key Hash&lt;/h3&gt;
&lt;p&gt;Just head over to the Key Hashes section in Quick Start. Add your package name and just the &apos;class&apos; name for the &apos;Default Activity Class Name&apos;. Make sure you save the development key hash. To generate a key hash, use this code snippet and then run your app.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;try {
            PackageInfo info = getPackageManager().getPackageInfo(
                    &quot;com.suleiman.parseapp&quot;,
                    PackageManager.GET_SIGNATURES);
            for (Signature signature : info.signatures) {
                MessageDigest md = MessageDigest.getInstance(&quot;SHA&quot;);
                md.update(signature.toByteArray());
                Log.d(&quot;KeyHash:&quot;, Base64.encodeToString(md.digest(), Base64.DEFAULT));
            }
        } catch (PackageManager.NameNotFoundException e) {

        } catch (NoSuchAlgorithmException e) {

        }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Copy the key hash from your logs. Head over to your app&apos;s Settings and paste your key hash there. This key is required to access any data from Facebook with their Graph API.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./facebook-login-with-parse-part-1/fb-dev-panel-744x525.png&quot; alt=&quot;fb-dev-panel&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; If you happen to get a key hash related error when running your app in the future (after the integration), Facebook will show your key hash along with your error. You can manually type that into your App&amp;gt; Settings.&lt;/p&gt;
&lt;h4&gt;Linking Facebook to Parse&lt;/h4&gt;
&lt;p&gt;Go to your Parse app&apos;s Settings&amp;gt; Authentication and enable Facebook. Copy over your &apos;App ID&apos; and &apos;App Secret&apos; from Facebook over to your Parse Settings.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./facebook-login-with-parse-part-1/link-fb-to-parse-744x376.png&quot; alt=&quot;link-fb-to-parse&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Open your &lt;em&gt;AndroidManifest.xml&lt;/em&gt; and add these directly below the &lt;em&gt;&lt;/em&gt; tag.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; 

        
...
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Initialize &lt;a href=&quot;https://parse.com/docs/android/api/com/parse/ParseFacebookUtils.html&quot;&gt;ParseFacebookUtils&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;ParseFacebookUtils allows Parse to hook up with Facebook. This makes sign up via Facebook as seamless as possible. We need to import a library for that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dependencies {
           ...
           compile &apos;com.parse:parsefacebookutils-v4-android:1.10.3@aar&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Initialize Parse with Facebook in your &lt;strong&gt;MyApp.java&lt;/strong&gt;&apos;s onCreate method. Make sure you do it AFTER Parse.initialize&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ParseFacebookUtils.initialize(this);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, for whichever Activity that will implement the login, head over to that very Activity.java and add this method.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        ParseFacebookUtils.onActivityResult(requestCode, resultCode, data);
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After this, if you want you can try a simple Facebook &lt;a href=&quot;https://developers.facebook.com/docs/android/graph&quot;&gt;GraphRequest&lt;/a&gt; or even signing up the user yourself via Facebook through Parse, if you&apos;re feeling bold enough! However this post has gone long enough, so head over to &lt;a href=&quot;https://blog.iamsuleiman.com/facebook-login-with-parse-part-2/&quot;&gt;Part 2&lt;/a&gt; for the rest.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Now give yourself a pat on the back if you&apos;ve made it this far. You&apos;ve successfully integrated both Parse AND Facebook SDK for your app, and that sir, is no ordinary feat! In the next part, we&apos;ll look at how to do a proper Facebook login, pull required user information, store it on Parse and then display it. Give yourselves some credit for making it to the end. Hope you&apos;ve been able to follow along. For further queries, fire away in the comments below and as always, I&apos;d be happy to help. Cheers.&lt;/p&gt;
</content:encoded></item><item><title>Tint Icons in Android for pre Lollipop</title><link>https://blog.iamsuleiman.com/tint-icons-in-android/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/tint-icons-in-android/</guid><description>Tint icons were first seen on Android Lollipop. The same can now be done on previous versions too with the help of Support Libraries. Here&apos;s on how to</description><pubDate>Sun, 21 Jun 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Tint icons were first seen on Android Lollipop. The same can now be done on previous versions too with the help of Support Libraries. Here&apos;s on how to tint your icons: 1. Retrieve your drawable and wrap it first. Then set the tint&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Drawable drawable = getyourdrawablehere;
drawable = DrawableCompat.wrap(drawable);
DrawableCompat.setTint(drawable, Color.GREEN);
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;Set the Tint mode&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;DrawableCompat.setTintMode(drawable, PorterDuff.Mode.SRC_IN);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you want to retrieve the original drawable, don&apos;t forget to unwrap using &lt;code&gt;DrawableCompat.unwrap()&lt;/code&gt; .&lt;/p&gt;
</content:encoded></item><item><title>Quick Return Pattern with Android Design Support Library</title><link>https://blog.iamsuleiman.com/quick-return-pattern-with-android-design-support-library/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/quick-return-pattern-with-android-design-support-library/</guid><description>The &apos;Quick Return&apos; is a famous UI pattern seen in Android apps. It aims to dedicate the screen&apos;s maximum possible real estate to content, instead of c</description><pubDate>Thu, 18 Jun 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The &apos;Quick Return&apos; is a famous UI pattern seen in Android apps. It aims to dedicate the screen&apos;s maximum possible real estate to content, instead of controls. With Android Design Support Library, the same which was harder in the past, is now quite easy!&lt;/p&gt;
&lt;h2&gt;Quick Return Pattern&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;This is similar to Google Now&apos;s search box. It scrolls off-screen with the rest of the scrollable content, but upon scrolling slightly up at any point, it scrolls back into view - &lt;strong&gt;&lt;a href=&quot;https://plus.google.com/+RomanNurik/posts/1Sb549FvpJt&quot;&gt;Roman Nurik&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You might have come across this in my &lt;a href=&quot;https://blog.iamsuleiman.com/implement-floating-action-button-fab-part-2/&quot;&gt;Implement a FAB&lt;/a&gt; post where I would&apos;ve showed you how to implement this which was quite a tedious process. The good news is, in this post the very same effect is quite easily achievable with pure XML only! Take a look at this video for a better understanding. &lt;a href=&quot;https://youtu.be/PL9s0IJ9oiI&quot;&gt;Watch on YouTube&lt;/a&gt; We can see a lot of famous apps implement the Quick Return pattern such as Google +, WhatsApp and Play Store. The Android Design Support Library enables us to achieve this pattern with minimal effort. Something which was an intensive process to do in the past!&lt;/p&gt;
&lt;h2&gt;When to use it?&lt;/h2&gt;
&lt;p&gt;The pattern works best when you have a long list of scrollable content. A perfect example would be a contacts list, a news feed and even a gallery. Content always takes top priority and giving maximum screen space to just that is essential. Screen real estate is all the more important in phones which have smaller displays compared to their tablet counterparts. Controls such as the Toolbar (ActionBar), Split Action Bar, Floating Action Button, all take up space and prove to be a hindrance. Hence really long scrollable content is the perfect opportunity for us to implement this pattern and hide such persistent controls. These can always be revealed upon scrolling up again. Also read:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/material-design-tabs-with-android-design-support-library/&quot;&gt;Material Design Tabs with Design Support Library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/toolbar-animation-with-android-design-support-library/&quot;&gt;Flexible Space with Image Pattern&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/parallax-scrolling-tabs-design-support-library/&quot;&gt;Parallax Scrolling Tabs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Layout&lt;/h2&gt;
&lt;p&gt;Let&apos;s take a look at how our XML structure will be first. The AppBarLayout will help us control the Toolbar behavior.&lt;/p&gt;
&lt;p&gt;If any of the new widgets don&apos;t make sense to you, then I highly recommend that you go through my &lt;a href=&quot;https://blog.iamsuleiman.com/toolbar-animation-with-android-design-support-library/&quot;&gt;previous post&lt;/a&gt; which clearly explains everything.&lt;/p&gt;
&lt;p&gt;Do note the highlighted lines as these two are key in making the Quick Return pattern actually work! The &lt;strong&gt;scroll&lt;/strong&gt; flag enables views to scroll off the screen, while &lt;strong&gt;enterAlways&lt;/strong&gt; enables the Quick Return pattern. The string resource &apos;&lt;strong&gt;appbar_scrolling_view_behavior&lt;/strong&gt;&apos; tells the AppBar how to react upon scrolling the RecyclerView.&lt;/p&gt;
&lt;h2&gt;Wrapping it up!&lt;/h2&gt;
&lt;p&gt;That&apos;s all there is to it really! Just don&apos;t forget to do the usual drill where you need to set up your Toolbar as ActionBar and then populate your RecyclerView! ;-) When you&apos;re done with all that, go ahead and run your app. Your Toolbar will now be responding to scroll in RecyclerView. The Quick Return pattern will be enabled. As you scroll down the Toolbar moves out of the screen and while scrolling down even slightly, the Toolbar moves back into the screen.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/quick-return-pattern-with-android-design-support-library/quick-return_opt.gif&quot; alt=&quot;quick return_opt&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Check out this code sample on &lt;a href=&quot;https://github.com/Suleiman19/Android-Material-Design-for-pre-Lollipop/blob/master/MaterialSample/app/src/main/java/com/suleiman/material/activities/QuickReturnActivity.java&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Maximizing screen real estate is of real importance for apps especially those running on phone that have small screens. Making use of the available space smartly allows us to hide what&apos;s not required, allowing our content to stand out. This eliminates hindrances, prioritizing the content our users want to see comfortably. &lt;strong&gt;NOTE:&lt;/strong&gt; The Design Support Library is the first of its kind and aims to achieve big. But being released recently, it is bound to have its bugs. Do subscribe (below) or &lt;a href=&quot;https://twitter.com/Suleiman_194&quot;&gt;Follow @Suleiman_194&lt;/a&gt; for instant updates on new posts, tips and tricks in Android design. Cheers!&lt;/p&gt;
</content:encoded></item><item><title>Create a Card Toolbar (Nested Toolbar) in Android</title><link>https://blog.iamsuleiman.com/create-a-card-toolbar/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/create-a-card-toolbar/</guid><description>I heard Android updated its Material Design specs, so I revisited the site(https://www.google.com/design/spec/layout/structure.htmlstructure-toolbars)</description><pubDate>Mon, 15 Jun 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I heard Android updated its Material Design specs, so I revisited the &lt;a href=&quot;https://www.google.com/design/spec/layout/structure.html#structure-toolbars&quot;&gt;site&lt;/a&gt; to check out what&apos;s new. While looking around the Layout Structure section, I came across a particular image &quot;&lt;strong&gt;Flexible toolbar and card toolbar&lt;/strong&gt;&quot;. So being the inquisitive person I am , I went ahead trying to replicate the pattern.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./create-a-card-toolbar/card-toolbar.png&quot; alt=&quot;card toolbar&quot; title=&quot;Flexible Toolbar and Card Toolbar&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In this post we&apos;ll look at how to make this. A Card Toolbar resting above another extended Toolbar. Also read: &lt;a href=&quot;https://blog.iamsuleiman.com/add-a-toolbar-elevation-on-pre-lollipop/&quot;&gt;Add a Toolbar Elevation on pre Lollipop&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Layout Structure&lt;/h2&gt;
&lt;p&gt;If you observe closely, the background is a regular Toolbar with an extended height. It doesn&apos;t have a menu, whereas the secondary Toolbar is set within a CardView, inflates a menu and a Title as well. There is a divider (View) that rests below the secondary Toolbar. Let&apos;s look at how our layout structure will look like first.&lt;/p&gt;
&lt;h3&gt;Extended Toolbar&lt;/h3&gt;
&lt;p&gt;The extended Toolbar takes double the default Toolbar height (i.e. 56dp x 2 = 112dp) keeping in mind that&apos;s the measurement for a portrait oriented phone. So you might want to add relevant values under your &lt;em&gt;dimens.xml&lt;/em&gt; for landscape and tablet sizes as well! However, I will cover the minimum dimen values here.&lt;/p&gt;
&lt;h4&gt;Toolbar Height&lt;/h4&gt;
&lt;p&gt;Below are the default Toolbar heights. Remember we need twice the Toolbar&apos;s height for the extended Toolbar. Mobile Landscape: 48dp Mobile Portrait: 56dp Tablet/Desktop: 64dp Under &lt;em&gt;res/values/&lt;strong&gt;dimens.xml&lt;/strong&gt;&lt;/em&gt; add this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;112dp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, under your &lt;em&gt;values-land&lt;/em&gt; and &lt;em&gt;values-sw600dp,&lt;/em&gt; add the same item with dimensions &lt;strong&gt;96dp&lt;/strong&gt; and &lt;strong&gt;128dp&lt;/strong&gt; respectively. If you&apos;re still wondering how I got those values, you might want to check &lt;a href=&quot;https://www.google.com/design/spec/layout/structure.html#structure-app-bar&quot;&gt;this&lt;/a&gt; out. So our extended Toolbar&apos;s XML will simply be this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    
    ...
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Card Toolbar&lt;/h3&gt;
&lt;p&gt;You might have noticed the card has some margins. The top margin is the Toolbar&apos;s height. We&apos;ll wrap the Toolbar in a LinearLayout, along with a 1dp tall View which holds the divider. The CardView side margins when used on a phone must be minimal (since it already lacks width). However for landscape and tablet forms, you could add side margins anywhere between Toolbar Height or Toolbar Height x 2.&lt;/p&gt;
&lt;h2&gt;Final Layout&lt;/h2&gt;
&lt;h2&gt;Final Setup&lt;/h2&gt;
&lt;p&gt;Lastly, we need a bit of Java to wrap things up so open your &lt;strong&gt;Activity.java&lt;/strong&gt; and setup your SECONDARY Toolbar (Card Toolbar) to be the ActionBar. This will use the inflated menu resource as well. Keep in mind the primary Toolbar (extended) on the top will be holding just the Navigation Drawer icon.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Card Toolbar as ActionBar (to inflate menu)
setSupportActionBar(mToolbar2);
getSupportActionBar().setTitle(&quot;Title&quot;);
// Extended Toolbar (holds drawer icon)
mToolbar1.setNavigationIcon(R.drawable.ic_action_menu);
mToolbar1.setNavigationOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
         // TODO: Handle Navigation Drawer menu click here
    }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With that we&apos;re done! You might have noticed how our layout is turning out to be on the Preview pane in Studio, while creating the XML layout. However do run the app and take a look, just in case ;-)&lt;/p&gt;
&lt;h2&gt;Divider Height Issue&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./create-a-card-toolbar/card-toolbar-align-e1434343318310.png&quot; alt=&quot;card-toolbar-align&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Note that the divider view below the Card Toolbar must align in height exactly with where the extended Toolbar&apos;s height ends. Now while the preview shows it just fine, when we actually run the app, this may not be the case leading to misalignment due to reasons unknown. However this can be resolved with a simple fix. Add a &lt;code&gt;layout_marginTop=&quot;-4dp&quot;&lt;/code&gt; to your Card Toolbar. Feel free to alter that value as you see fit in order to align the divider and extended Toolbar exactly. Though &lt;strong&gt;-4dp&lt;/strong&gt; works perfect for me! So with all things in place, run your app for the last time. It will be perfectly aligned now! Try it on different screen sizes and orientations to check if it aligns properly. Here are final screenshots from my phone, portrait and landscape orientation.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./create-a-card-toolbar/Screenshot_2015-06-15-10-13-46.png&quot; alt=&quot;Card Toolbar final result, landscape orientation&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./create-a-card-toolbar/Screenshot_2015-06-15-10-13-12.png&quot; alt=&quot;Card Toolbar final result, portrait orientation&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Click to buy Nexus 9&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;NOTE: This layout style works best on tablet devices. Nexus 9 is a brilliant tablet device and one of the best to buy.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;In this post the fact that the Toolbar can be used flexibly like another other view is reinforced. We&apos;ve added two Toolbars in our layout and attached one inside a CardView. Check out the code sample for this on &lt;a href=&quot;https://github.com/Suleiman19/Android-Material-Design-for-pre-Lollipop/blob/master/MaterialSample/app/src/main/java/com/suleiman/material/activities/NestedToolbarActivity.java&quot;&gt;GitHub&lt;/a&gt;. Do subscribe (below) or &lt;a href=&quot;https://twitter.com/Suleiman_194&quot;&gt;Follow @Suleiman_194&lt;/a&gt; for instant updates on new posts, tips and tricks in Android design!&lt;/p&gt;
</content:encoded></item><item><title>Add a Toolbar Elevation on pre Lollipop</title><link>https://blog.iamsuleiman.com/add-a-toolbar-elevation-on-pre-lollipop/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/add-a-toolbar-elevation-on-pre-lollipop/</guid><description>Being a Material Design lover, I get put off by that default flat Toolbar with no shadow or elevation. It&apos;s alright on Lollipop devices as it gives us</description><pubDate>Mon, 08 Jun 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Being a Material Design lover, I get put off by that default flat Toolbar with no shadow or elevation. It&apos;s alright on Lollipop devices as it gives us a nice shadow by default, but pre Lollipop doesn&apos;t. While that&apos;s too bad, we can take care of that real quick! After you&apos;re done with this post, your Toolbars on pre Lollipop will never be plain and boring again! Also read: &lt;a href=&quot;https://blog.iamsuleiman.com/create-a-card-toolbar/&quot;&gt;Create a Card Toolbar (Nested Toolbar)&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Faking a Toolbar Elevation&lt;/h2&gt;
&lt;p&gt;Since we can&apos;t use the actual Toolbar elevation property for pre Lollipop devices, we&apos;ll imitate one by using :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;9-patch PNG&lt;/li&gt;
&lt;li&gt;XML gradient&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Personally, I find the XML method more clean, so we&apos;ll go with the second one.&lt;/p&gt;
&lt;h3&gt;Shadow Drawable&lt;/h3&gt;
&lt;p&gt;Create a new XML file &lt;em&gt;res/drawable/&lt;strong&gt;shadow.xml&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Here we set a gradient from top to bottom of an opacity of black to transparent respectively.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./add-a-toolbar-elevation-on-pre-lollipop/toolbar-shadow-744x1240.png&quot; alt=&quot;shadow.xml&quot; title=&quot;shadow.xml&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Creating the Toolbar&lt;/h3&gt;
&lt;p&gt;Now the trick doesn&apos;t lie in modifying the Toolbar as such, but in simply adding a &lt;em&gt;View&lt;/em&gt; below it. Usually we may define a Toolbar in a separate XML file and call it in via the &lt;em&gt;&lt;/em&gt; tag. We&apos;ll stick to the same format (to avoid large and complex layouts). Create a layout &lt;em&gt;res/layout/&lt;strong&gt;toolbar_shadow.xml&lt;/strong&gt;&lt;/em&gt; and add this:&lt;/p&gt;
&lt;h3&gt;Calling it in&lt;/h3&gt;
&lt;p&gt;Now with that in place, all we need to do is to reference this in our activity&apos;s layout like this:&lt;/p&gt;
&lt;p&gt;That&apos;s it we&apos;re done! Take a look at the results yourself and see the difference.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./add-a-toolbar-elevation-on-pre-lollipop/toolbar-with-shadow.png&quot; alt=&quot;Toolbar with shadow on pre-Lollipop&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./add-a-toolbar-elevation-on-pre-lollipop/toolbar-without-shadow.png&quot; alt=&quot;Toolbar without shadow on pre-Lollipop&quot; /&gt;&lt;/p&gt;
&lt;p&gt;on pre Lollipop&lt;/p&gt;
&lt;h2&gt;Toolbar Elevation on Lollipop&lt;/h2&gt;
&lt;p&gt;You can default to the elevation property for Lollipop devices. Now in some cases, as with the new Design support library&apos;s new widgets, after the animation the Toolbars by default have a shadow. So do the Tabs. You could reference the shadow&apos;s &lt;em&gt;View&lt;/em&gt; via an id, and removing it with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;shadowView.setVisibility(View.GONE);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then set the Toolbar elevation with&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;toolbar.setElevation(4);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;But Wait!&lt;/h3&gt;
&lt;p&gt;In my opinion, just stick to using the &lt;strong&gt;shadow.xml&lt;/strong&gt; on both pre Lollipop and Lollipop devices. Why? The difference isn&apos;t much and is hardly noticeable.&lt;/p&gt;
&lt;p&gt;This is a better trade-off than having to handle it in code, where you must remove the shadow view, then elevate it. That is just a lot of code handling and possible layout inconsistency, you&apos;re much better off this way. One must not waste time as a developer to get something like that to work.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;With this way, you can now mimic an elevation for your Toolbars on pre Lollipop as well. We created a shadow drawable in XML using a gradient property. Also you&apos;ve probably accepted the fact that its okay to continue using the same drawable on post Lollipop as well, being a well worth sacrifice.&lt;/p&gt;
&lt;p&gt;Do subscribe (below) for instant updates as I continue to bring you more awesome content like this!&lt;/p&gt;
</content:encoded></item><item><title>Material Design Tabs with Android Design Support Library</title><link>https://blog.iamsuleiman.com/material-design-tabs-with-android-design-support-library/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/material-design-tabs-with-android-design-support-library/</guid><description>This is my third post where I continue to bring you more from the Design Support Library. Let&apos;s look at adding a Material Design Tab strip for our app</description><pubDate>Sat, 06 Jun 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This is my third post where I continue to bring you more from the Design Support Library. Let&apos;s look at adding a Material Design Tab strip for our apps with on scroll animations.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Tabs make it easy to explore and switch between different views. Provides a way for displaying grouped content.&lt;/p&gt;
&lt;p&gt;– &lt;a href=&quot;https://material.io/components/tabs/&quot;&gt;Material Design, Tab Component&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This article has been updated for AndroidX!&lt;/p&gt;
&lt;h2&gt;Material Design Tabs made easy&lt;/h2&gt;
&lt;p&gt;You can see Material Design tabs popularly on the Play Store app, and more recently on WhatsApp as well (after their Material Design update).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./material-design-tabs-with-android-design-support-library/play-e1433589207850.png&quot; alt=&quot;material design tabs in play store app&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Material Design Tabs in Play Store&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./material-design-tabs-with-android-design-support-library/Screenshot_2015-06-06-16-18-28-e1433588805526.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Tabs in WhatsApp&lt;/p&gt;
&lt;p&gt;To implement Tabs earlier, we had to rely on external libraries. Also, let&apos;s not forget the hide on scroll animations which we had to make ourselves!&lt;/p&gt;
&lt;p&gt;When you&apos;re done reading this post, you&apos;ll be able to create amazing Material Design tabs for your apps. Like the ones above.&lt;/p&gt;
&lt;p&gt;So let&apos;s get to it!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Also read:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/parallax-scrolling-tabs-design-support-library/&quot;&gt;Parallax Scrolling Tabs with Design Support Library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/toolbar-animation-with-android-design-support-library/&quot;&gt;Flexible space with header image pattern&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/easy-navigation-drawer-with-design-support-library/&quot;&gt;Quick Material Design Navigation Drawer with Design Support&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Layout&lt;/h3&gt;
&lt;p&gt;Have you closely observed how Tabs actually behave?&lt;/p&gt;
&lt;p&gt;When you click a Tab, it becomes active and slides in a new screen. Rather a new sub-screen called &lt;code&gt;Fragment&lt;/code&gt;. We either tap a Tab, or swipe left or right to access adjacent Tabs.&lt;/p&gt;
&lt;p&gt;Tabs are typically found anchored to the bottom of the &lt;code&gt;Toolbar&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In essence, the entirety of those Tab screens are Fragments, which will be handled by a &lt;a href=&quot;http://developer.android.com/reference/android/support/v4/view/ViewPager.html&quot;&gt;&lt;code&gt;ViewPager&lt;/code&gt;&lt;/a&gt;. Think of it like a gallery slideshow.&lt;/p&gt;
&lt;p&gt;But before we dive into all of that, let&apos;s setup our main layout.&lt;/p&gt;
&lt;p&gt;Here&apos;s a skeleton of the layout.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;androidx.coordinatorlayout.widget.CoordinatorLayout&amp;gt;
   &amp;lt;com.google.android.material.appbar.AppBarLayout&amp;gt;
      &amp;lt;androidx.appcompat.widget.Toolbar /&amp;gt;
      &amp;lt;!-- The Tab rests directly below the Toolbar, attached below it --&amp;gt;
      &amp;lt;com.google.android.material.tabs.TabLayout /&amp;gt;
   &amp;lt;/com.google.android.material.appbar.AppBarLayout&amp;gt;
   &amp;lt;!-- Helps handing the Fragments to load for each Tab --&amp;gt;
   &amp;lt;android.support.v4.view.ViewPager /&amp;gt;
&amp;lt;/androidx.coordinatorlayout.widget.CoordinatorLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For creating Tabs, we use the &lt;strong&gt;&lt;code&gt;TabLayout&lt;/code&gt;&lt;/strong&gt; widget class. This is a new widget, part of the Design Support Library.&lt;/p&gt;
&lt;p&gt;Additionally, you might notice other new widgets as well. If you&apos;re not familiar with them, I strongly suggest you go through &lt;a href=&quot;https://blog.iamsuleiman.com/toolbar-animation-with-android-design-support-library/&quot;&gt;this post&lt;/a&gt; first.&lt;/p&gt;
&lt;p&gt;That&apos;s the skeleton of our &lt;code&gt;Activity&lt;/code&gt; layout. Let&apos;s start defining it now. Open your Activity&apos;s &lt;strong&gt;&lt;em&gt;layout.xml&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;&amp;gt;

    &amp;lt;com.google.android.material.appbar.AppBarLayout
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:theme=&quot;@style/ThemeOverlay.AppCompat.Dark.ActionBar&quot;&amp;gt;

        &amp;lt;androidx.appcompat.widget.Toolbar
            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;?attr/actionBarSize&quot;
            android:background=&quot;?attr/colorPrimary&quot;
            app:layout_scrollFlags=&quot;scroll|enterAlways&quot;
            app:popupTheme=&quot;@style/ThemeOverlay.AppCompat.Light&quot; /&amp;gt;

        &amp;lt;com.google.android.material.tabs.TabLayout
            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;wrap_content&quot; /&amp;gt;
    &amp;lt;/com.google.android.material.appbar.AppBarLayout&amp;gt;

    &amp;lt;android.support.v4.view.ViewPager
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;match_parent&quot;
        app:layout_behavior=&quot;@string/appbar_scrolling_view_behavior&quot; /&amp;gt;

&amp;lt;/androidx.coordinatorlayout.widget.CoordinatorLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The scroll flags for the &lt;code&gt;Toolbar&lt;/code&gt; specify how it must behave upon scroll (i.e. its animation).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;scroll|enterAlways&lt;/code&gt;&lt;/strong&gt; says make my &lt;code&gt;Toolbar&lt;/code&gt; react to scroll events. Hide it when scrolling down, and reveal it when scrolling back up.&lt;/p&gt;
&lt;p&gt;This behavior will be indicated by our &lt;code&gt;ViewPager&lt;/code&gt; which will be hold our Fragments. The Fragments hold our scrollable view. So when we scroll down a list, the &lt;code&gt;Toolbar&lt;/code&gt; knows when to react.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./material-design-tabs-with-android-design-support-library/tab-layout-e1433590592736.png&quot; alt=&quot;Tabs attached below Toolbar&quot; /&gt;&lt;/p&gt;
&lt;p&gt;TabLayout and Toolbar in XML preview&lt;/p&gt;
&lt;h4&gt;Setting up TabLayout&lt;/h4&gt;
&lt;p&gt;That&apos;s our main layout. Now open up &lt;em&gt;YourActivity.java.&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;final Toolbar toolbar = findViewById(R.id.tabanim_toolbar);
setSupportActionBar(toolbar);

final ViewPager viewPager = findViewById(R.id.tabanim_viewpager);
setupViewPager(viewPager);

TabLayout tabLayout = findViewById(R.id.tabanim_tabs);
tabLayout.setupWithViewPager(viewPager);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First, start off by setting up your &lt;code&gt;Toolbar&lt;/code&gt;. Then define the &lt;code&gt;ViewPager&lt;/code&gt;. We&apos;ll attach an Adapter to in the &lt;strong&gt;&lt;code&gt;setupViewPager()&lt;/code&gt;&lt;/strong&gt; method. Finally define the &lt;code&gt;TabLayout&lt;/code&gt;, and attach the &lt;code&gt;ViewPager&lt;/code&gt; to it.&lt;/p&gt;
&lt;p&gt;Remember that we must attach an adapter to the &lt;code&gt;ViewPager&lt;/code&gt; first. Then attach the &lt;code&gt;ViewPager&lt;/code&gt; to &lt;code&gt;TabLayout&lt;/code&gt;.&lt;/p&gt;
&lt;h5&gt;&lt;code&gt;setupViewPager()&lt;/code&gt; &lt;strong&gt;method&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;Here I will simply initialize a &lt;strong&gt;ViewPagerAdapter&lt;/strong&gt; (our custom adapter class which I will explain in a moment) and add 3 fragments to it.&lt;/p&gt;
&lt;p&gt;For simplicity&apos;s sake, I will be attached the same &lt;code&gt;Fragment&lt;/code&gt; thrice which different backgrounds. However in a real app scenario, you would be attaching different once.&lt;/p&gt;
&lt;p&gt;Let&apos;s assume you have 3 tabs. &lt;em&gt;Games, Movies, Books&lt;/em&gt;. Then you should be loading their respective fragments here in ORDER of the tabs.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private void setupViewPager(ViewPager viewPager) {
 ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
 adapter.addFrag(new DummyFragment(
  ContextCompat.getColor(this, R.color.blue_grey)), &quot;CAT&quot;);
 adapter.addFrag(new DummyFragment(
  ContextCompat.getColor(this, R.color.amber)), &quot;DOG&quot;);
 adapter.addFrag(new DummyFragment(
  ContextCompat.getColor(this, R.color.cyan)), &quot;MOUSE&quot;);
 viewPager.setAdapter(adapter);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So let&apos;s define our Tabs and give each one a name. &lt;em&gt;Cat, Dog and Mouse&lt;/em&gt; (for the lack of better names) will be my 3 Tabs.&lt;/p&gt;
&lt;h4&gt;Defining our Adapter&lt;/h4&gt;
&lt;p&gt;Remember that &lt;strong&gt;ViewPagerAdapter&lt;/strong&gt; I told you about? Let&apos;s create a class for it now, extend &lt;a href=&quot;http://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html&quot;&gt;&lt;code&gt;FragmentPagerAdapter&lt;/code&gt;&lt;/a&gt; and implement the required methods.&lt;/p&gt;
&lt;p&gt;We need to store, first our Fragments itself, and then the Tab titles. We&apos;ll do this with a &lt;code&gt;List&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private final List&amp;lt;Fragment&amp;gt; mFragmentList = new ArrayList&amp;lt;&amp;gt;();
private final List&amp;lt;String&amp;gt; mFragmentTitleList = new ArrayList&amp;lt;&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our entire Adapter class will look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class ViewPagerAdapter extends FragmentPagerAdapter {
 private final List &amp;lt; Fragment &amp;gt; mFragmentList = new ArrayList &amp;lt; &amp;gt; ();
 private final List &amp;lt; String &amp;gt; mFragmentTitleList = new ArrayList &amp;lt; &amp;gt; ();

 public ViewPagerAdapter(FragmentManager manager) {
  super(manager);
 }

 @Override
 public Fragment getItem(int position) {
  return mFragmentList.get(position);
 }

 @Override
 public int getCount() {
  return mFragmentList.size();
 }

 public void addFrag(Fragment fragment, String title) {
  mFragmentList.add(fragment);
  mFragmentTitleList.add(title);
 }

 @Override
 public CharSequence getPageTitle(int position) {
  return mFragmentTitleList.get(position);
 }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that &lt;strong&gt;&lt;code&gt;addFrag()&lt;/code&gt;&lt;/strong&gt; is my own custom method. I&apos;m using it to add Fragments and its titles to the &lt;code&gt;ViewPager&lt;/code&gt; adapter.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./material-design-tabs-with-android-design-support-library/tabs-defined-e1433590539228.png&quot; alt=&quot;tabs-defined&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Tabs with ViewPager Adapter&lt;/p&gt;
&lt;h5&gt;Tab Fragment&lt;/h5&gt;
&lt;p&gt;Now that we&apos;ve done all this, you might be wondering what is &apos;&lt;em&gt;&lt;strong&gt;DummyFragment&lt;/strong&gt;&lt;/em&gt;&apos; and why its showing an error?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;DummyFragment&lt;/em&gt; is to be your &lt;code&gt;Fragment&lt;/code&gt; (obvious from the name), which holds the layout content. This is what we see when we swipe to each Tab. Ideally, you should be loading a different &lt;code&gt;Fragment&lt;/code&gt; for each tab.&lt;/p&gt;
&lt;p&gt;The layout could be anything. But I don&apos;t want to complicate things.&lt;/p&gt;
&lt;p&gt;Just be sure for testing, to make a list long enough so that its scrollable. This will allow the &lt;a href=&quot;https://blog.iamsuleiman.com/quick-return-pattern-with-android-design-support-library/&quot;&gt;Quick Return scroll animation&lt;/a&gt; to work.&lt;/p&gt;
&lt;p&gt;I encourage you to create your own layouts for the Tab &lt;code&gt;Fragment&lt;/code&gt;. You could refer mine, but if you&apos;re like &lt;em&gt;&quot;Hey, I can do this!&lt;/em&gt;&quot;, then good job! Scroll down to the next section.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    public static class DummyFragment extends Fragment {
        int color;
        SimpleRecyclerAdapter adapter;

        public DummyFragment() {
        }

        @SuppressLint(&quot;ValidFragment&quot;)
        public DummyFragment(int color) {
            this.color = color;
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.dummy_fragment, container, false);

            final FrameLayout frameLayout = view.findViewById(R.id.dummyfrag_bg);
            frameLayout.setBackgroundColor(color);

            RecyclerView recyclerView = view.findViewById(R.id.dummyfrag_scrollableview);

            LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity().getBaseContext());
            recyclerView.setLayoutManager(linearLayoutManager);
            recyclerView.setHasFixedSize(true);

            List&amp;lt;String&amp;gt; list = Arrays.asList(VersionModel.data);

            adapter = new SimpleRecyclerAdapter(list);
            recyclerView.setAdapter(adapter);

            return view;
        }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./material-design-tabs-with-android-design-support-library/tabs-with-list-e1433591036641.png&quot; alt=&quot;tabs with list&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Tabs with Fragments attached&lt;/p&gt;
&lt;h6&gt;Tab Listener&lt;/h6&gt;
&lt;p&gt;We can interact with the &lt;code&gt;TabLayout&lt;/code&gt; and dictate what must happen when selecting a Tab, unselecting, reselecting and so forth.&lt;/p&gt;
&lt;p&gt;While we&apos;re staying on topic, let me show you how we can add such a listener to it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
 @Override
 public void onTabSelected(TabLayout.Tab tab) {
  viewPager.setCurrentItem(tab.getPosition());

  switch (tab.getPosition()) {
   case 0:
    showToast(&quot;One&quot;);
    break;
   case 1:
    showToast(&quot;Two&quot;);
    break;
   case 2:
    showToast(&quot;Three&quot;);
    break;
  }
 }

 @Override
 public void onTabUnselected(TabLayout.Tab tab) {}

 @Override
 public void onTabReselected(TabLayout.Tab tab) {}
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note &lt;strong&gt;&lt;code&gt;viewPager.setCurrentItem(tab.getPosition())&lt;/code&gt;&lt;/strong&gt; handles changing the &lt;code&gt;Fragment&lt;/code&gt; based on Tab click.&lt;/p&gt;
&lt;p&gt;Yes, all it takes is to use &lt;strong&gt;&lt;code&gt;setOnTabSelectedListener&lt;/code&gt;&lt;/strong&gt; with &lt;strong&gt;&lt;code&gt;TabLayout.OnTabSelectedListener()&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Just for demonstration, I&apos;ll show a simple &lt;code&gt;Toast&lt;/code&gt; when you tap a Tab item. This works not only when tapping, but also when swiping left or right! In essence, a &lt;code&gt;Toast&lt;/code&gt; pops each time the &lt;code&gt;Fragment&lt;/code&gt; loads into view.&lt;/p&gt;
&lt;h6&gt;v23.0.0 Tab Listener Fix:&lt;/h6&gt;
&lt;p&gt;With the release of Android Marshmallow, libraries got updated to 23.0.0 including the Design Support Library. This update somehow broke the tab listener in a viewpager + tab combination. So if click listener for the tabs stops working for you, here is a suggested &lt;a href=&quot;https://code.google.com/p/android/issues/detail?id=183123&quot;&gt;workaround&lt;/a&gt; for it, suggested by Chris Banes himself.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Material Design Tabs in Action&lt;/h3&gt;
&lt;p&gt;Let&apos;s take a breath and break down what we&apos;ve accomplished so far:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Created our main &lt;code&gt;TabLayout&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Initialized a &lt;code&gt;ViewPager&lt;/code&gt; and attached an Adapter (&lt;em&gt;ViewPagerAdapter&lt;/em&gt;) to it&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Attached the &lt;code&gt;ViewPager&lt;/code&gt; to our Tabs&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Created the &lt;code&gt;Fragment&lt;/code&gt; content to supply our &lt;code&gt;ViewPager&lt;/code&gt; with&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Finally with all that code behind us, lets run our app and see how it looks like.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/hFNQ2mp7Lpg&quot;&gt;Watch on YouTube&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;That&apos;s it! We&apos;ve got some great looking Material Design Tabs (without a third party library). Created the needed adapter and even got those snazzy on scroll animations for our &lt;code&gt;Toolbar&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Note the Tab underline highlight takes &lt;strong&gt;colorAccent&lt;/strong&gt; by default. Also, did you just notice we got those animations to work just by defining it in XML? No Java. Cheers!&lt;/p&gt;
&lt;p&gt;Thats what Android Design Support library allows us to do. Making the easy stuff easier.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Suleiman19/Android-Material-Design-for-pre-Lollipop/blob/master/MaterialSample/app/src/main/java/com/suleiman/material/activities/TabAnimationActivity.java&quot;&gt;Get Source Code from GitHub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;How are you using TabLayout in your apps? Have anything else to add? Let me know in the comments.&lt;/p&gt;
</content:encoded></item><item><title>Toolbar Animation with Android Design Support Library</title><link>https://blog.iamsuleiman.com/toolbar-animation-with-android-design-support-library/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/toolbar-animation-with-android-design-support-library/</guid><description>In this Android tutorial we&apos;ll create an on scroll, collapsing Toolbar animation. The Design support library for Android makes it easy to create great</description><pubDate>Wed, 03 Jun 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In this Android tutorial we&apos;ll create an on scroll, collapsing &lt;code&gt;Toolbar&lt;/code&gt; animation.&lt;/p&gt;
&lt;p&gt;The Design support library for Android makes it easy to create great animations. Let&apos;s look at how to create an app with a collapsing &lt;code&gt;Toolbar&lt;/code&gt; animation. It&apos;s know as the &lt;strong&gt;Flexible Space with Image pattern&lt;/strong&gt;, a popular scrolling technique.&lt;/p&gt;
&lt;p&gt;I didn&apos;t know this pattern actually had a name until &lt;a href=&quot;https://plus.google.com/+SuleimanAliShakir/posts/YeLRBoeoPJr&quot;&gt;Ian Lake happened to point it out for me&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This article has been updated for AndroidX!&lt;/p&gt;
&lt;h2&gt;Flexible Space with Image Pattern&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;A scrolling technique that supports an image header with a scrollable view below it. Upon scrolling, the &apos;Flexible Space&apos; (image header) gets tinted with or. At the same time, it collapses into a Toolbar.&lt;/p&gt;
&lt;p&gt;– &lt;a href=&quot;https://material.io/guidelines/patterns/scrolling-techniques.html#scrolling-techniques-scrolling&quot;&gt;Material Design guidelines&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This pattern is a popular scrolling technique. In familiar terms, you can see this in WhatsApp’s contact detail screen.&lt;/p&gt;
&lt;p&gt;Here’s the step-by-step screenshots of the Flexible Space animation. Should give you a clear picture of what’s going on.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./toolbar-animation-with-android-design-support-library/flexible_space_animation_steps.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Flexible Space with Image Pattern - step by step&lt;/p&gt;
&lt;p&gt;Notice the &lt;code&gt;Toolbar&lt;/code&gt; dynamically changes color, depending on the image. It takes on the most dominant color present in the image.&lt;/p&gt;
&lt;p&gt;We can do this with the &lt;a href=&quot;https://developer.android.com/training/material/palette-colors&quot;&gt;Palette API&lt;/a&gt;, but more on that later.&lt;/p&gt;
&lt;p&gt;You might immediately start to freak out with the amount of code it might take. But rest assured, there&apos;s no scary Java code to write. Most of it is XML, so cheers to that!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Other Design Support Library tutorials:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/easy-navigation-drawer-with-design-support-library/&quot;&gt;Material Design Navigation Drawer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/parallax-scrolling-tabs-design-support-library/&quot;&gt;Parallax Scrolling Tabs with header image&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/material-design-tabs-with-android-design-support-library/&quot;&gt;Material Design Tabs Layout&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.iamsuleiman.com/quick-return-pattern-with-android-design-support-library/&quot;&gt;Quick Return pattern&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;Here’s a useful index for navigating the article. Sections include not just how to implement the pattern. But also how to do it correctly, in terms of UI and UX.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Table of Contents&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#getting-started&quot;&gt;Getting Started&lt;/a&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#layout_structure&quot;&gt;Layout Structure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#design_support_ui_widgets&quot;&gt;Design Support UI Widgets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#defining-the-xml-layout&quot;&gt;Defining the XML Layout&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#getting-the-parallax-scroll-right&quot;&gt;Getting the Parallax Scroll right&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#floating-action-button&quot;&gt;Floating Action Button&lt;/a&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#the-hidden-action&quot;&gt;The Hidden Action&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#updating-toolbar-menu&quot;&gt;Updating Toolbar Menu&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#dynamic-colors-with-palette-api&quot;&gt;Dynamic Colors with Palette API&lt;/a&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#using-the-palette-api&quot;&gt;Using the Palette API&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#complete-activity-code&quot;&gt;Complete Activity Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#toolbar-animation-in-action&quot;&gt;Toolbar Animation in Action&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;Start by adding the Design Support Library to your &lt;em&gt;app/build.gradle&lt;/em&gt; file.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br /&gt;
The Design Support package is now part of &lt;a href=&quot;https://developer.android.com/jetpack/androidx&quot;&gt;Android X&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;dependencies {
…
implementation &apos;androidx.appcompat:appcompat:1.1.0&apos;
implementation &apos;com.google.android.material:material:1.0.0&apos;
}&lt;/p&gt;
&lt;h3&gt;Layout Structure&lt;/h3&gt;
&lt;p&gt;As always, we’ll get started with the XML first. Open your &lt;strong&gt;activity.xml&lt;/strong&gt; layout.&lt;/p&gt;
&lt;p&gt;Here’s the layout skeleton.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;androidx.coordinatorlayout.widget.CoordinatorLayout&amp;gt;
   &amp;lt;com.google.android.material.appbar.AppBarLayout&amp;gt;
      &amp;lt;com.google.android.material.appbar.CollapsingToolbarLayout&amp;gt;
         &amp;lt;ImageView /&amp;gt;
         &amp;lt;androidx.appcompat.widget.Toolbar /&amp;gt;
      &amp;lt;/com.google.android.material.appbar.CollapsingToolbarLayout&amp;gt;
   &amp;lt;/com.google.android.material.appbar.AppBarLayout&amp;gt;
   &amp;lt;!-- Your scrollable content here --&amp;gt;
&amp;lt;/androidx.coordinatorlayout.widget.CoordinatorLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Design Support UI Widgets&lt;/h4&gt;
&lt;p&gt;I understand if all these layouts might appear new to you. But you won&apos;t have to worry. I&apos;ll do my best to explain them in the easiest way.&lt;/p&gt;
&lt;h5&gt;&lt;a href=&quot;http://developer.android.com/reference/android/support/design/widget/CoordinatorLayout.html&quot;&gt;1. CoordinatorLayout&lt;/a&gt;&lt;/h5&gt;
&lt;p&gt;A powerful &lt;code&gt;FrameLayout&lt;/code&gt; that specifies behavior for child views for various interactions. It also allows anchoring of floating views in your layout.&lt;/p&gt;
&lt;h5&gt;&lt;a href=&quot;http://developer.android.com/reference/android/support/design/widget/AppBarLayout.html&quot;&gt;2. AppBarLayout&lt;/a&gt;&lt;/h5&gt;
&lt;p&gt;It is a special kind of vertical &lt;code&gt;LinearLayout&lt;/code&gt;. It helps respond to its children’s scroll events (scroll gestures). Additionally, it&apos;s responsible for implementing many features of Material Design’s &lt;code&gt;AppBarLayout&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But, there&apos;s one thing to note. Its usage relies on being a direct child within &lt;code&gt;CoordinatorLayout&lt;/code&gt;. The layout skeleton above demonstrates this.&lt;/p&gt;
&lt;h5&gt;&lt;a href=&quot;http://developer.android.com/reference/android/support/design/widget/CollapsingToolbarLayout.html&quot;&gt;3. CollapsingToolbarLayout&lt;/a&gt;&lt;/h5&gt;
&lt;p&gt;It is a &lt;code&gt;Toolbar&lt;/code&gt; wrapper which makes the ‘Flexible Space’ pattern possible. It collapses the image header while decreasing the expanded title to a &lt;code&gt;Toolbar&lt;/code&gt; title.&lt;/p&gt;
&lt;p&gt;What’s left is the &lt;code&gt;ImageView&lt;/code&gt; which holds our actual header’s image and &lt;code&gt;Toolbar&lt;/code&gt; which we’re familiar with.&lt;/p&gt;
&lt;h5&gt;4. FloatingActionButton&lt;/h5&gt;
&lt;p&gt;I&apos;m sure you&apos;re familiar with what a Floating Action Button is, aren&apos;t you? Android gave it a thumbs up by giving us an official UI widget. It&apos;s a part of the Design Support Library.&lt;/p&gt;
&lt;p&gt;More on this later.&lt;/p&gt;
&lt;h4&gt;Defining the XML Layout&lt;/h4&gt;
&lt;p&gt;Alright, with that out of the way lets get to the actual XML.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;A word of caution. The layout below might look threatening in size!&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    android:fitsSystemWindows=&quot;true&quot;&amp;gt;

    &amp;lt;com.google.android.material.appbar.AppBarLayout
        android:id=&quot;@+id/appbar&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;@dimen/appbar_header_height&quot;
        android:fitsSystemWindows=&quot;true&quot;
        android:theme=&quot;@style/ThemeOverlay.AppCompat.Dark.ActionBar&quot;&amp;gt;

        &amp;lt;com.google.android.material.appbar.CollapsingToolbarLayout
            android:id=&quot;@+id/collapsing_toolbar&quot;
            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;match_parent&quot;
            android:fitsSystemWindows=&quot;true&quot;
            app:contentScrim=&quot;?attr/colorPrimary&quot;
            app:expandedTitleMarginStart=&quot;@dimen/activity_margin_content&quot;
            app:layout_scrollFlags=&quot;scroll|exitUntilCollapsed|snap&quot;&amp;gt;

            &amp;lt;ImageView
                android:id=&quot;@+id/header&quot;
                android:layout_width=&quot;match_parent&quot;
                android:layout_height=&quot;match_parent&quot;
                android:background=&quot;@drawable/header&quot;
                android:fitsSystemWindows=&quot;true&quot;
                android:scaleType=&quot;centerCrop&quot;
                app:layout_collapseMode=&quot;parallax&quot; /&amp;gt;

            &amp;lt;View
                android:layout_width=&quot;match_parent&quot;
                android:layout_height=&quot;80dp&quot;
                android:layout_gravity=&quot;top&quot;
                android:background=&quot;@drawable/scrim_topdown&quot;
                android:fitsSystemWindows=&quot;true&quot; /&amp;gt;

            &amp;lt;View
                android:layout_width=&quot;match_parent&quot;
                android:layout_height=&quot;160dp&quot;
                android:layout_gravity=&quot;bottom&quot;
                android:background=&quot;@drawable/scrim&quot; /&amp;gt;

            &amp;lt;androidx.appcompat.widget.Toolbar
                android:id=&quot;@+id/anim_toolbar&quot;
                android:layout_width=&quot;match_parent&quot;
                android:layout_height=&quot;?attr/actionBarSize&quot;
                app:layout_collapseMode=&quot;pin&quot;
                app:popupTheme=&quot;@style/ThemeOverlay.AppCompat.Light&quot; /&amp;gt;

        &amp;lt;/com.google.android.material.appbar.CollapsingToolbarLayout&amp;gt;

    &amp;lt;/com.google.android.material.appbar.AppBarLayout&amp;gt;

    &amp;lt;androidx.recyclerview.widget.RecyclerView
        android:id=&quot;@+id/scrollableview&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;match_parent&quot;
        android:clipToPadding=&quot;false&quot;
        android:paddingTop=&quot;@dimen/activity_margin_content&quot;
        android:paddingBottom=&quot;@dimen/activity_margin_content&quot;
        app:layout_behavior=&quot;@string/appbar_scrolling_view_behavior&quot;
        tools:listItem=&quot;@layout/item_dessert&quot; /&amp;gt;

    &amp;lt;com.google.android.material.floatingactionbutton.FloatingActionButton
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_margin=&quot;@dimen/fab_margin&quot;
        android:clickable=&quot;true&quot;
        android:focusable=&quot;true&quot;
        android:src=&quot;@drawable/ic_action_add&quot;
        app:backgroundTint=&quot;#279AF1&quot;
        app:fabSize=&quot;normal&quot;
        app:layout_anchor=&quot;@+id/appbar&quot;
        app:layout_anchorGravity=&quot;bottom|right|end&quot; /&amp;gt;

&amp;lt;/androidx.coordinatorlayout.widget.CoordinatorLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is not complex code. XML just tends to be a little verbose. But you&apos;re welcome to try replicating the Flexible Space scroll animation in Java. Then I&apos;m sure you&apos;d truly appreciate how easy the Design Support library is!&lt;/p&gt;
&lt;p&gt;However, I have highlighted the essential lines you need to focus on.&lt;/p&gt;
&lt;h5&gt;What you need to know from this?&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;line 24:&lt;/em&gt; &lt;code&gt;layout_scrollFlags&lt;/code&gt;&lt;br /&gt;
Tells the &lt;code&gt;CollapsingToolbarLayout&lt;/code&gt; and its children, how to behave on a scroll.&lt;br /&gt;
Here’s what the flags mean, straight from the developer’s blog:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;scroll&lt;/strong&gt;:&lt;br /&gt;
this flag should be set for all views that want to scroll off-screen. For views that do not use this flag, they’ll remain pinned to the top of the screen.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;exitUntilCollapsed&lt;/strong&gt;:&lt;br /&gt;
causes the view to scroll off until it is ‘collapsed’ before exiting&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;snap&lt;/strong&gt;:&lt;br /&gt;
enables the expanded view to snap to either a collapsed state, or expanded state. There is no in-between state. If the &lt;code&gt;View&lt;/code&gt; has been dragged more towards expanding, it expands completely. If its dragged more towards collapsing, the &lt;code&gt;View&lt;/code&gt; collapses completely.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;line 33&lt;/em&gt;: &lt;code&gt;layout_collapseMode&lt;/code&gt;&lt;br /&gt;
Indicates how the &lt;code&gt;ImageView&lt;/code&gt; reacts while collapsing on-scroll.&lt;br /&gt;
There are 2 collapse modes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;COLLAPSE_MODE_PARALLAX&lt;/code&gt; (use for &lt;code&gt;ImageView&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;COLLAPSE_MODE_PIN&lt;/code&gt; (use for &lt;code&gt;Toolbar&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;line 63&lt;/em&gt;: &lt;code&gt;layout_behavior&lt;/code&gt;&lt;br /&gt;
The &lt;code&gt;CoordinatorLayout&lt;/code&gt; performs most of its magic using &lt;a href=&quot;https://developer.android.com/reference/android/support/design/widget/CoordinatorLayout.Behavior.html&quot;&gt;&lt;code&gt;Behavior&lt;/code&gt;&lt;/a&gt;. Behaviors tell how its child Views must interact with each other.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;line 73&lt;/em&gt;: &lt;code&gt;layout_anchor&lt;/code&gt;&lt;br /&gt;
Remember we spoke about anchoring Views earlier? This attribute tells &lt;code&gt;FloatingActionButton&lt;/code&gt; to anchor&apos; itself to &lt;code&gt;AppBarLayout&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;line 74&lt;/em&gt;: &lt;code&gt;layout_anchorGravity&lt;/code&gt;&lt;br /&gt;
This attribute tells our &lt;code&gt;View&lt;/code&gt; where to display, on its anchor &lt;code&gt;View&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here’s what the Android Studio’s Preview pane shows us.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./toolbar-animation-with-android-design-support-library/toolbar_animation_xml_layout_preview.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Flexible Space with Image Pattern - XML Layout Preview&lt;/p&gt;
&lt;p&gt;But wait. Does the expanded title look clear enough to you? I’m sure it’s not.&lt;/p&gt;
&lt;p&gt;Whenever you display a label (&lt;code&gt;TextView&lt;/code&gt;) against a background image, use a &apos;&lt;em&gt;scrim&lt;/em&gt;&apos;. It will help make the text more readable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;
Use a Scrim for clear, readable Text&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A Scrim is a semi-transparent gradient layer that helps Text appear more readable against backgrounds.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Just below your &lt;code&gt;ImageView&lt;/code&gt;, add a simple View with a gradient &lt;code&gt;Drawable&lt;/code&gt; as background.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Here’s the &lt;code&gt;Drawable&lt;/code&gt; scrim.&lt;/p&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;See the difference for yourself.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./toolbar-animation-with-android-design-support-library/flexible_space_scrim.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Header without(Before) and with(After) Scrim&lt;/p&gt;
&lt;p&gt;While the difference is subtle, the latter is much better right? Additionally, you can apply another scrim for the Toolbar. It can help the back and overflow icons be more visible. I leave this as an exercise for you.&lt;/p&gt;
&lt;p&gt;There are &lt;a href=&quot;https://blog.iamsuleiman.com/techniques-to-display-text-overlay-background-images/&quot;&gt;many other techniques that you can use&lt;/a&gt; to display text over images.&lt;/p&gt;
&lt;h6&gt;Getting the Parallax Scroll right&lt;/h6&gt;
&lt;p&gt;I’ve already mentioned a hint above on parallax scroll. But there’s more to it. We can achieve parallax scrolling with &lt;code&gt;ImageView&lt;/code&gt; by setting its &lt;code&gt;layout_collapseMode&lt;/code&gt; to &lt;em&gt;&lt;code&gt;parallax&lt;/code&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Parallax Scrolling involves the background moving at a slower rate to the foreground.&lt;/p&gt;
&lt;p&gt;– &lt;a href=&quot;http://www.creativebloq.com/web-design/parallax-scrolling-1131762&quot;&gt;Creativebloq.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Did you notice an extra collapse mode attribute for the &lt;code&gt;Toolbar&lt;/code&gt;? Yes, you must use this as well. Why? Because, while the &lt;code&gt;ImageView&lt;/code&gt; should collapse, the &lt;code&gt;Toolbar&lt;/code&gt; must persist on scrolling.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Toolbar&lt;/code&gt; must use &lt;code&gt;collapseMode:pin&lt;/code&gt;, because we want it to persist and remain on top, as the user scrolls down.&lt;/p&gt;
&lt;p&gt;Note that I haven’t set any color for the &lt;code&gt;Toolbar&lt;/code&gt;. The &lt;code&gt;CollapsingToolbarLayout&lt;/code&gt; takes care of this. It dynamically picks up a color from our image and sets it to the &lt;code&gt;Toolbar&lt;/code&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Floating Action Button&lt;/h3&gt;
&lt;p&gt;Let&apos;s look at the Floating Action Button for a bit. I&apos;ll stick to calling it FAB from now on. If you tried to create a FAB earlier, you&apos;d realize how hard it was. Yes, my previous posts on the FAB are now redundant. Sigh.&lt;/p&gt;
&lt;p&gt;But with the Design Support Library, that&apos;s not the case anymore. The layout above shows, how easy it is!&lt;/p&gt;
&lt;p&gt;Notice that I haven&apos;t explicitly defined a size for the FAB. By default, it takes its regular width and height of &lt;strong&gt;56dp&lt;/strong&gt;. But, you can define this by using the following attribute.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;app:fabSize=&quot;regular&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Optionally, you can set the &lt;code&gt;fabSize&lt;/code&gt; as &lt;em&gt;&lt;code&gt;mini&lt;/code&gt;&lt;/em&gt;, which is a miniature version of the FAB at &lt;strong&gt;40dp&lt;/strong&gt; in size.&lt;/p&gt;
&lt;p&gt;Next, in the layout, we position the FAB with alignment to the &lt;code&gt;AppBarLayout&lt;/code&gt;. We do this with the &lt;code&gt;layout_anchor&lt;/code&gt; attribute.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    &amp;lt;com.google.android.material.floatingactionbutton.FloatingActionButton
        ...
        app:layout_anchor=&quot;@+id/appbar&quot;
        app:layout_anchorGravity=&quot;bottom|right|end&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./toolbar-animation-with-android-design-support-library/flexible_space_fab_layoutanchor_appbar.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;FAB without and with anchor attribute&lt;/p&gt;
&lt;p&gt;That’s a wrap for the XML part. The good news is, this XML is all that&apos;s required to trigger the Flexible Space scroll animation.&lt;/p&gt;
&lt;p&gt;But wait! There’s still one thing that seems a bit off. What about the FAB’s action? After scrolling, the action goes hidden. It becomes available, only when you scroll, all the way to the top.&lt;/p&gt;
&lt;h4&gt;The Hidden Action&lt;/h4&gt;
&lt;p&gt;Once the AppBar collapses, we need to show the FAB’s action somewhere.&lt;/p&gt;
&lt;p&gt;Now I’m not saying this is the recommended approach. But my suggestion is that once the FAB vanishes, we add the action to the Toolbar’s menu.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/toolbar-animation-with-android-design-support-library/flexible_space_toolbar_menu.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Dynamic Toolbar Menu item&lt;/p&gt;
&lt;p&gt;To do this we’ll need a listener first. We have to listen to the when the &lt;code&gt;AppBarLayout&lt;/code&gt; expands and collapses. To be precise, we need an &lt;strong&gt;OffsetChangedListener&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If the &lt;code&gt;AppBarLayout&lt;/code&gt;’s ‘&lt;strong&gt;verticalOffset&lt;/strong&gt;’ is zero, then its fully expanded. So when the verticalOffset is almost equal to the fully expanded height, add the action to &lt;code&gt;Toolbar&lt;/code&gt;’s menu.&lt;/p&gt;
&lt;p&gt;First, let’s look at how to set the listener. Here’s how to do it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
  @Override
  public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
   //  Vertical offset == 0 indicates appBar is fully expanded.
   if (Math.abs(verticalOffset) &amp;gt; 200) {
    appBarExpanded = false;
    invalidateOptionsMenu();
   } else {
    appBarExpanded = true;
    invalidateOptionsMenu();
   }
  }
 });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are some key takeaway points from the above code snippet.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;verticalOffset&lt;/code&gt; returns negative values, so we wrap it with &lt;code&gt;Math.abs(verticalOffset)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;appBarExpanded&lt;/code&gt; is a boolean flag that I’m maintaining to know when &lt;code&gt;AppBarLayout&lt;/code&gt; is expanded or collapsed&lt;/li&gt;
&lt;li&gt;&lt;code&gt;invalidateOptionsMenu()&lt;/code&gt; is called every time our &lt;code&gt;AppBarLayout&lt;/code&gt;’s height crosses a threshold (200)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now I wish there was a simpler way to know the &lt;code&gt;AppBarLayout&lt;/code&gt;’s state. But I guess this solution works good enough.&lt;/p&gt;
&lt;h5&gt;Updating Toolbar Menu&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;invalidateOptionsMenu()&lt;/code&gt; helps update our &lt;code&gt;Toolbar&lt;/code&gt; &lt;code&gt;Menu&lt;/code&gt;. But we need to tell our &lt;code&gt;Menu&lt;/code&gt; when to add and remove our extra Action.&lt;/p&gt;
&lt;p&gt;Note that the FAB’s action is an ‘Add’ function.&lt;/p&gt;
&lt;p&gt;First, we need a reference for the existing &lt;code&gt;Menu&lt;/code&gt;. You can get this from the &lt;code&gt;onCreateOptionsMenu()&lt;/code&gt; method.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override
 public boolean onCreateOptionsMenu(Menu menu) {
  getMenuInflater().inflate(R.menu.menu_main, menu);
  collapsedMenu = menu;
  return true;
 }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;collapsedMenu&lt;/code&gt; is a global variable of type &lt;code&gt;Menu&lt;/code&gt;. It allows us to keep a copy of the original &lt;code&gt;Menu&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Next, we need to update our &lt;code&gt;Menu&lt;/code&gt;. We’re already calling &lt;code&gt;invalidateOptionsMenu()&lt;/code&gt; in the scroll listener. This will trigger the &lt;code&gt;onPrepareOptionsMenu()&lt;/code&gt; method. Hence, we’ll add our dynamic &lt;code&gt;Menu&lt;/code&gt; logic here.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
     if (collapsedMenu != null &amp;amp;&amp;amp;
      (!appBarExpanded || collapsedMenu.size() != 1)) {
      //collapsed
      collapsedMenu.add(&quot;Add&quot;)
       .setIcon(R.drawable.ic_action_add)
       .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
     } else {
      //expanded
     }
     return super.onPrepareOptionsMenu(collapsedMenu);
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You’ll notice that I haven’t done anything for the expanded state. We don’t need to either. I’ll tell you why.&lt;/p&gt;
&lt;p&gt;After &lt;code&gt;onPrepareOptionsMenu()&lt;/code&gt;, the &lt;code&gt;onCreateOptionsMenu()&lt;/code&gt; is called. What do we need to do in the expanded state? The FAB becomes visible, which means we should hide the ‘Add’ action from &lt;code&gt;Toolbar&lt;/code&gt; menu.&lt;/p&gt;
&lt;p&gt;Since &lt;code&gt;onCreateOptionsMenu()&lt;/code&gt; inflates the original &lt;code&gt;Menu&lt;/code&gt; again, we don’t have to worry about manually removing it.&lt;/p&gt;
&lt;p&gt;So now, when the FAB hides, its Action will be added to &lt;code&gt;Toolbar&lt;/code&gt; &lt;code&gt;Menu&lt;/code&gt;. When the &lt;code&gt;AppBarLayout&lt;/code&gt; collapses and FAB hides, the ‘Add’ action becomes visible in the &lt;code&gt;Toolbar&lt;/code&gt; &lt;code&gt;Menu&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now all that remains is to do the usual UI initialization in Java. So let&apos;s setup our Toolbar and then call in the Palette API.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Dynamic Colors with Palette API&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;The palette API is a support library that extracts prominent colors from images.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To use the Palette library, we first need to add it to your project. So open up your &lt;em&gt;app/build.gradle&lt;/em&gt; and add the following line.&lt;/p&gt;
&lt;p&gt;dependencies {
…
implementation &apos;androidx.palette:palette:1.0.0&apos;
}&lt;/p&gt;
&lt;p&gt;Remember that we have to initialize our UI first. So open your &lt;em&gt;Activity.java&lt;/em&gt; and type away. Or copy-paste this instead.&lt;/p&gt;
&lt;p&gt;toolbar = (Toolbar) findViewById(R.id.anim_toolbar);
setSupportActionBar(toolbar);&lt;/p&gt;
&lt;p&gt;collapsingToolbar = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
collapsingToolbar.setTitle(&quot;Suleiman Ali Shakir&quot;);&lt;/p&gt;
&lt;p&gt;ImageView header = (ImageView) findViewById(R.id.header);&lt;/p&gt;
&lt;p&gt;Now you might ask me, why I have set a title for &lt;code&gt;CollapsingToolbarLayout&lt;/code&gt;, instead of &lt;code&gt;Toolbar&lt;/code&gt;? That&apos;s a valid question.&lt;/p&gt;
&lt;p&gt;Take a look at the Flexible Space with Image scroll animation. Yes, the GIF which I shared at the beginning of this post. Notice there&apos;s an expanded title, which on scrolling, collapses into the &lt;code&gt;Toolbar&lt;/code&gt; title.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;CollapsingToolbarLayout&lt;/code&gt; handles this for us. Hence we set the title for that, instead of a &lt;code&gt;Toolbar&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Additionally, the &lt;code&gt;CollapsingToolbarLayout&lt;/code&gt; also handles tinting our &lt;code&gt;Toolbar&lt;/code&gt; using the Palette API. I’ll show you how to do this.&lt;/p&gt;
&lt;h4&gt;Using the Palette API&lt;/h4&gt;
&lt;p&gt;First, pass the &apos;header&apos; &lt;code&gt;ImageView&lt;/code&gt;’s bitmap to the Palette API. Then the API will generate colors based on the header image, in an AsyncTask.&lt;/p&gt;
&lt;p&gt;Once it completes, we can fetch a color we want and set it to &lt;code&gt;CollapsingToolbarLayout&lt;/code&gt;. This, in turn, tints our &lt;code&gt;Toolbar&lt;/code&gt; to our chosen color, when we scroll.&lt;/p&gt;
&lt;p&gt;Let’s look at some code.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
 @Override
 public void onGenerated(Palette palette) {
  int vibrantColor = palette.getVibrantColor(R.color.primary_500);
  collapsingToolbar.setContentScrimColor(vibrantColor);
  collapsingToolbar.setStatusBarScrimColor(R.color.black_trans80);
 }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I am fetching my bitmap from my resources directory. But, in a real-world scenario, you would be downloading the image from an URL. Then saving it as a bitmap and passing that to the Palette API.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;Palette API&lt;/em&gt; offers several color options (variations). Here are the basic four:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Light&lt;/li&gt;
&lt;li&gt;Dark&lt;/li&gt;
&lt;li&gt;Vibrant&lt;/li&gt;
&lt;li&gt;Muted&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./toolbar-animation-with-android-design-support-library/palette-library-color-profiles_2-1_2x.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Image credits: &lt;a href=&quot;https://developer.android.com/training/material/palette-colors.html&quot;&gt;developer.android.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can also increase the number of colors generated from the image. Or you can even retrieve the entire color swatch! If you’re interested in playing around with the &lt;em&gt;Palette API&lt;/em&gt;, I’d suggest you go through &lt;a href=&quot;https://chris.banes.me/2014/10/20/palette-v21/&quot;&gt;Chris Banes’ post&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Complete Activity Code&lt;/h3&gt;
&lt;p&gt;Here’s the complete &lt;code&gt;Activity&lt;/code&gt; for your reference.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class AnimateToolbar extends AppCompatActivity {

    private CollapsingToolbarLayout collapsingToolbar;
    private AppBarLayout appBarLayout;
    private RecyclerView recyclerView;

    private DessertAdapter dessertAdapter;

    private Menu collapsedMenu;
    private boolean appBarExpanded = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_animate_toolbar);

        final Toolbar toolbar = (Toolbar) findViewById(R.id.anim_toolbar);
        setSupportActionBar(toolbar);
        if (getSupportActionBar() != null)
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        appBarLayout = (AppBarLayout) findViewById(R.id.appbar);

        collapsingToolbar = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
        collapsingToolbar.setTitle(getString(R.string.android_desserts));

        Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
                R.drawable.header);

        Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
            @SuppressWarnings(&quot;ResourceType&quot;)
            @Override
            public void onGenerated(Palette palette) {
                int vibrantColor = palette.getVibrantColor(R.color.primary_500);
                collapsingToolbar.setContentScrimColor(vibrantColor);
                collapsingToolbar.setStatusBarScrimColor(R.color.black_trans80);
            }
        });

        recyclerView = (RecyclerView) findViewById(R.id.scrollableview);
        //  Use when your list size is constant for better performance
        recyclerView.setHasFixedSize(true);

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(linearLayoutManager);

        dessertAdapter = new DessertAdapter(this);
        recyclerView.setAdapter(dessertAdapter);

        appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                Log.d(AnimateToolbar.class.getSimpleName(), &quot;onOffsetChanged: verticalOffset: &quot; + verticalOffset);

                //  Vertical offset == 0 indicates appBar is fully expanded.
                if (Math.abs(verticalOffset) &amp;gt; 200) {
                    appBarExpanded = false;
                    invalidateOptionsMenu();
                } else {
                    appBarExpanded = true;
                    invalidateOptionsMenu();
                }
            }
        });

    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        if (collapsedMenu != null
                &amp;amp;&amp;amp; (!appBarExpanded || collapsedMenu.size() != 1)) {
            //collapsed
            collapsedMenu.add(&quot;Add&quot;)
                    .setIcon(R.drawable.ic_action_add)
                    .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
        } else {
            //expanded
        }
        return super.onPrepareOptionsMenu(collapsedMenu);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        collapsedMenu = menu;
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                finish();
                return true;
            case R.id.action_settings:
                return true;
        }
        if (item.getTitle() == &quot;Add&quot;) {
            Toast.makeText(this, &quot;clicked add&quot;, Toast.LENGTH_SHORT).show();
        }

        return super.onOptionsItemSelected(item);
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;Output - Toolbar Animation Results&lt;/h2&gt;
&lt;p&gt;Finally, we’ve completed what’s needed for the &lt;code&gt;Toolbar&lt;/code&gt; animation. In fact, much more than what’s required! So go ahead, run your app and watch the magic.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/toolbar-animation-with-android-design-support-library/flexible_space_toolbar_animation.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Toolbar animation output&lt;/p&gt;
&lt;p&gt;To be honest, it was surprising to see such a smooth &lt;code&gt;Toolbar&lt;/code&gt; animation. Even the FAB beautifully reacts upon touch with a higher elevation.&lt;/p&gt;
&lt;p&gt;**Source Code:&lt;br /&gt;
**&lt;a href=&quot;https://github.com/Suleiman19/Android-Material-Design-for-pre-Lollipop/blob/master/MaterialSample/app/src/main/java/com/suleiman/material/activities/AnimateToolbar.java&quot;&gt;Available on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Material Design is a powerful visual language that can help you design a brilliant app. The Design Support Library makes it easy to create powerful animations, like this. It allows us to create rich app experiences our users can enjoy.&lt;/p&gt;
&lt;p&gt;How are you using the Design Support Library? Do you have your own take on the &apos;Flexible Space with Image&apos; animation pattern? Let me know in the comments below.&lt;/p&gt;
&lt;p&gt;Also, if you liked reading this, don&apos;t forget to share with your friends.&lt;/p&gt;
</content:encoded></item><item><title>Easy Navigation Drawer with Design Support Library</title><link>https://blog.iamsuleiman.com/easy-navigation-drawer-with-design-support-library/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/easy-navigation-drawer-with-design-support-library/</guid><description>In Google I/O 2015, a lot of new stuff was revealed. One particular thing that caught my eye was the release of Android&apos;s Design Support Library, whic</description><pubDate>Sat, 30 May 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In Google I/O 2015, a lot of new stuff was revealed. One particular thing that caught my eye was the release of Android&apos;s Design Support Library, which I found out thanks to Chris Banes&apos; tweet. &lt;a href=&quot;https://twitter.com/chrisbanes/status/603984333309784064&quot;&gt;https://twitter.com/chrisbanes/status/603984333309784064&lt;/a&gt; I&apos;ll show you how to create a Material Design Navigation Drawer almost effortlessly, how to handle Drawer click events and orientation changes too!&lt;/p&gt;
&lt;h2&gt;What is the new Design Support Library in Android?&lt;/h2&gt;
&lt;p&gt;Before we get to that, I feel its best if we get comfortable with what the Design support library actually is.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;With a little help from the new Android Design Support Library, we’re bringing a number of important material design components to all developers and to all Android 2.1 or higher devices- &lt;a href=&quot;http://android-developers.blogspot.in/2015/05/android-design-support-library.html&quot;&gt;android-developers.blogspot.in&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It includes components such as a NavigationView for Drawer, Floating Action Buttons, Snackbar, Tabs and a motion and scroll framework as well.&lt;/p&gt;
&lt;h3&gt;Navigation Drawer- then and now&lt;/h3&gt;
&lt;p&gt;Earlier making a Navigation Drawer in Android, took considerable effort and with the arrival of Material Design, including a header view and stuff, things got even harder.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./easy-navigation-drawer-with-design-support-library/navigation-drawer-then-and-now-744x418.png&quot; alt=&quot;navigation drawer google+ material design &quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Design Support Library, Our Savior&lt;/h3&gt;
&lt;p&gt;To make lives easier we needed to rely on external libraries to create a Material Design Navigation Drawer in Android (unless you were brave enough to attempt it yourself). But thanks to Design Support library, this is now very simple to do. Let&apos;s get started making an awesome Material Design Navigation Drawer for our Android app.&lt;/p&gt;
&lt;h2&gt;Using the Design support library&lt;/h2&gt;
&lt;p&gt;We&apos;ll start off by adding its dependency in Gradle. &lt;code&gt;compile &apos;com.android.support:design:22.2.0&apos;&lt;/code&gt; Since the library depends on the AppCompat and support-v4 libraries, we can replace those two dependencies with JUST this.&lt;/p&gt;
&lt;h2&gt;Navigation Drawer Layout&lt;/h2&gt;
&lt;p&gt;Go to your activity XML layout and structure your DrawerLayout like this:&lt;/p&gt;
&lt;p&gt;With this as the base, let&apos;s add in our &lt;em&gt;Toolbar&lt;/em&gt; layout with:  &lt;code&gt;&amp;lt;include layout=&quot;@layout/toolbar&quot; /&amp;gt;&lt;/code&gt;. Remember we can open the Drawer by tapping the burger icon as well, and for that we need a Toolbar. Note the new NavigationView. This comes from the Design support library. You can define its &lt;strong&gt;headerLayout&lt;/strong&gt; and must assign a menu resource for it. The &lt;strong&gt;fitsSystemWindows&lt;/strong&gt; attribute tells Android to draw this view behind the Status Bar. So when you open the Navigation Drawer, it appears behind a transparent Status Bar.&lt;/p&gt;
&lt;h3&gt;Drawer Menu&lt;/h3&gt;
&lt;p&gt;This is like your regular menu resource you use for your Toolbar ActionBar, but with a slight change. All menu items must be in a &lt;strong&gt;group&lt;/strong&gt;. (Unless you want to categorize your menu items in groups). It&apos;s &lt;strong&gt;checkableBehaviour&lt;/strong&gt; MUST be single.&lt;/p&gt;
&lt;h4&gt;Navigation Drawer Divider&lt;/h4&gt;
&lt;p&gt;If you wish to add a divider between your menu items, then simply add items in another group with a different ID. So all items residing in the second group will be separated from the first by a divider.&lt;/p&gt;
&lt;h3&gt;Header Layout&lt;/h3&gt;
&lt;p&gt;For the Drawer&apos;s Header layout, we create another XML layout that contains a simple &lt;em&gt;ImageView&lt;/em&gt; and &lt;em&gt;TextView&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;You could add whatever you need, but I&apos;m going to keep it simple with this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./easy-navigation-drawer-with-design-support-library/nav-drawer-header-view.png&quot; alt=&quot;navigation drawer header view&quot; /&gt;&lt;/p&gt;
&lt;p&gt;That is all the XML we&apos;ll be seeing for this post. Let&apos;s dig into some Java now.&lt;/p&gt;
&lt;h2&gt;Setting up the Activity&lt;/h2&gt;
&lt;p&gt;Open up your &lt;strong&gt;Activity.java&lt;/strong&gt;. Here we need to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Initialize the Toolbar&lt;/li&gt;
&lt;li&gt;Handle Drawer click events&lt;/li&gt;
&lt;li&gt;Handle orientation changes&lt;/li&gt;
&lt;li&gt;Introduce the Drawer to 1st time users (via Preference)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;1. Initialize the Toolbar&lt;/h3&gt;
&lt;p&gt;Frankly, I like to keep my o_nCreate()_ method free of clutter. So we&apos;ll create a method for this and call it in.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private void setUpToolbar() {
       mToolbar = (Toolbar) findViewById(R.id.toolbar);
       if (mToolbar != null) {
           setSupportActionBar(mToolbar);
       }
   }
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. Set up Navigation Drawer&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;private void setUpNavDrawer() {
       if (mToolbar != null) {
           getSupportActionBar().setDisplayHomeAsUpEnabled(true);
           mToolbar.setNavigationIcon(R.drawable.ic_drawer);
           mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View v) {
                   mDrawerLayout.openDrawer(GravityCompat.START);
               }
           });
       }

   }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here we&apos;re allowing the Toolbar (ActionBar) to display a home as up button, and supplying the icon for it. Then define its click listener where we open the Navigation Drawer upon click. Remember to call this method in o_nCreate()_ as well.&lt;/p&gt;
&lt;h3&gt;3. Handle Drawer click events&lt;/h3&gt;
&lt;p&gt;While the Drawer opens/ closes using the &lt;em&gt;DrawerLayout&lt;/em&gt; as a reference, the click events for the list items (menu) is handled by the &lt;em&gt;NavigationView&lt;/em&gt; via its &lt;strong&gt;setNavigationItemSelectedListener&lt;/strong&gt;**()** method.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
           @Override
           public boolean onNavigationItemSelected(MenuItem menuItem) {

               menuItem.setChecked(true);

               switch (menuItem.getItemId()) {
                   case R.id.navigation_item_1:
                       Snackbar.make(mContentFrame, &quot;Item One&quot;,                
                           Snackbar.LENGTH_SHORT).show();
                       mCurrentSelectedPosition = 0;
                       return true;
                   case R.id.navigation_item_2:
                       Snackbar.make(mContentFrame, &quot;Item Two&quot;, 
                           Snackbar.LENGTH_SHORT).show();
                       mCurrentSelectedPosition = 1;
                       return true;
                   default:
                       return true;
               }
           }
       });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Within the switch case is where we&apos;ll actually be handling our Drawer&apos;s item clicks. I will explain a bit later on why we need to track &lt;code&gt;mCurrentSelectedPosition&lt;/code&gt;. If you wish to handle Fragment transactions with your Navigation Drawer, just remember that it stays the same as before. Just below your Toolbar add a &lt;em&gt;FrameLayout&lt;/em&gt; like this:&lt;/p&gt;
&lt;p&gt;You can handle the fragment transactions under the switch case. This is all we need to get our Material Style Navigation Drawer with Design support library up and running. But honestly, if you plan on implementing something: Do it good, or don&apos;t bother doing it. With that being said, that last 2 parts is handling the drawer upon orientation changes (so your app doesn&apos;t crash when you flip the phone) and showing the Drawer for the first time to users (part of the guidelines).&lt;/p&gt;
&lt;h3&gt;4. Handling Orientation Changes&lt;/h3&gt;
&lt;p&gt;If the phone &lt;a href=&quot;http://developer.android.com/guide/topics/resources/runtime-changes.html&quot;&gt;orientation changes&lt;/a&gt;, the app will redraw or reload the activity to adapt to the new orientation. So when this happens, data existing during the previous load must be held. Loss of this data during the redraw results in a crash. Remember we used &lt;code&gt;mCurrentSelectedPosition&lt;/code&gt; a bit earlier when handling our Drawer clicks? Well, we&apos;re going to use that now. This is used to track which item on the Drawer was clicked, by storing its position. If you don&apos;t follow what I&apos;m saying, with what we&apos;ve done until now, go ahead and run your app. Tap any item on the Drawer apart from the default and flip your phone in landscape. You&apos;ll note that what you selected is reset. We&apos;re going to prevent that. To handle the state before and after the orientation change, we need to implement two methods:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that &lt;strong&gt;STATE_SELECTED_POSITION&lt;/strong&gt; is our key. We&apos;ll transfer &lt;em&gt;mCurrentSelectedPosition&lt;/em&gt;&apos;s value to a Bundle and save it. Upon restoring, we recover that value from the bundle using the key. Before we change the orientation, we want to save the last position we clicked. Once that&apos;s done, we need to restore the data on reload.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION, 0);
        Menu menu = mNavigationView.getMenu();
        menu.getItem(mCurrentSelectedPosition).setChecked(true);
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We retrieve our stored position data via a Bundle and then make that menu item checked. In your Activity&apos;s &lt;em&gt;onCreate()&lt;/em&gt; method, immediately after initializing your views and before calling your setup methods, add this.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (savedInstanceState != null) {
           mCurrentSelectedPosition =  
             savedInstanceState.getInt(STATE_SELECTED_POSITION);
           mFromSavedInstanceState = true;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this our Navigation Drawer will now handle orientation changes properly without crashes. If you have no idea about what these methods mean, then &lt;a href=&quot;http://developer.android.com/training/basics/activity-lifecycle/recreating.html&quot;&gt;this&lt;/a&gt; should give you a better idea.&lt;/p&gt;
&lt;h3&gt;4. Introduce Drawer First Time&lt;/h3&gt;
&lt;p&gt;When a user launches an app for the first time, we must open the drawer and show it to them. We&apos;ll do this using Preference. First off, add these two methods in your Activity.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static void saveSharedSetting(Context ctx, String settingName, String settingValue) {
       SharedPreferences sharedPref = ctx.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE);
       SharedPreferences.Editor editor = sharedPref.edit();
       editor.putString(settingName, settingValue);
       editor.apply();
   }

   public static String readSharedSetting(Context ctx, String settingName, String defaultValue) {
       SharedPreferences sharedPref = ctx.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE);
       return sharedPref.getString(settingName, defaultValue);
   }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preference file is  &lt;code&gt;private static final String PREFERENCES_FILE = &quot;yourappname_settings&quot;;&lt;/code&gt; We&apos;ll store a simple true/ false value in our Preference settings file and use that to know whether the app is launched for the first time or not. Initially read your preference with this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mUserLearnedDrawer = Boolean.valueOf(readSharedSetting(this, PREF_USER_LEARNED_DRAWER, &quot;false&quot;));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;PREF_USER_LEARNED_DRAWER&lt;/strong&gt; is my key (String type) which I use to fetch my Preference value. Now, go to where you initialize your DrawerLayout (setUpNavDrawer() method) and add these lines:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (!mUserLearnedDrawer) {
           mDrawerLayout.openDrawer(GravityCompat.START);
           mUserLearnedDrawer = true;
           saveSharedSetting(this, PREF_USER_LEARNED_DRAWER, &quot;true&quot;);
       }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the user hasn&apos;t learned about the Drawer (not seen it yet), then open the Drawer and set the learned preference to true. We now have a complete working Navigation Drawer:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/easy-navigation-drawer-with-design-support-library/navigation-drawer-material-design.gif&quot; alt=&quot;navigation drawer material design&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Note the deliberate slow down while closing the Drawer. The Status Bar overlaps the Navigation Drawer. This is quite easy to achieve. You just need to add this to your theme in &lt;strong&gt;v-21 styles.xml&lt;/strong&gt;. &lt;code&gt;&amp;lt;item name=&quot;android:windowTranslucentStatus&quot;&amp;gt;true&amp;lt;/item&amp;gt;&lt;/code&gt; Check out the working sample over at my &lt;a href=&quot;https://github.com/Suleiman19/Android-Material-Design-for-pre-Lollipop/blob/master/MaterialSample/app/src/main/java/com/suleiman/material/activities/NavDrawerActivity.java&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;That&apos;s it. I know the post was pretty long, but let&apos;s just see what we&apos;ve achieved: We&apos;ve managed to create a fully working Material Design Navigation Drawer with Design Support library in Android, which handles orientation changes perfectly and also greets users for the first time on app launch! While that was a mouthful, I&apos;m sure you realize that this is actually a walk in the park considering how hard a Material Design Navigation Drawer was to create in the past! :-) Do subscribe (below) or &lt;a href=&quot;https://twitter.com/Suleiman_194&quot;&gt;Follow @Suleiman_194&lt;/a&gt; for instant updates as I continue to bring you more awesome content!&lt;/p&gt;
</content:encoded></item><item><title>Android M</title><link>https://blog.iamsuleiman.com/android-m/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/android-m/</guid><description>Android Lollipop came in fast, went out faster! Welcome Android M. The Developer Preview was made available along with its reveal in Google I/O 2015. </description><pubDate>Thu, 28 May 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Android Lollipop came in fast, went out faster! Welcome Android M. The Developer Preview was made available along with its reveal in Google I/O 2015. Along with it came a slew of features, some which were being asked for a while and some, totally new. Here are the top 6 features in Android M.&lt;/p&gt;
&lt;h2&gt;1. App Permissions&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./android-m/perm-744x418.png&quot; alt=&quot;perm&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Android M finally simplifies app permissions by a great extent! You don&apos;t have to agree to permissions you don&apos;t need anymore. Android M allows you to selectively turn off permissions for specific features, restricting apps from using them. You can choose your permissions and see which apps have access to it. This is good news for app developers as well as its faster to get users up and running compared to the previous permission model. Android M allows for a more seamless app install process.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-m/android-m-app-permissions-420x747.png&quot; alt=&quot;android m app permissions&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;2. Web Experience&lt;/h2&gt;
&lt;p&gt;Web today is pushing its priority towards mobile as more and more users prefer to browse that way. Android M keeps their experience in mind and provides a better way to improve that very experience.&lt;/p&gt;
&lt;h3&gt;Custom Chrome Tabs&lt;/h3&gt;
&lt;p&gt;With this feature, Android M allows you to open links from within your app into a &apos;Custom Chrome Tab&apos; that overlays your app screen seamlessly with a transition. The Custom Chrome Tab, adapts to match the look and feel of your app so that you can comfortably browse its content.&lt;/p&gt;
&lt;h2&gt;3. App Links&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./android-m/verify-links-744x418.png&quot; alt=&quot;verify links&quot; /&gt;&lt;/p&gt;
&lt;p&gt;App linking is now made possible with Android M. Links can now be provided in the app via Intents in the Manifest file. This allows content to be more trusted and verifiable making the user aware of the content before actually tapping on it!&lt;/p&gt;
&lt;h2&gt;4. Android Pay&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./android-m/android-pay-e1432876691791-744x379.png&quot; alt=&quot;android pay&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Say goodbye to your wallet!&lt;/p&gt;
&lt;p&gt;Your phone&apos;s going to take care of your payments from now on thanks to Android M! Android Pay was made with three things in mind:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Simplicity&lt;/li&gt;
&lt;li&gt;Security&lt;/li&gt;
&lt;li&gt;Choice&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The payment method is very easy to use and can instantly help you make payments from your phone. This means lesser digging your wallet for those notes, and more of paying quick (like a boss). The payment process itself is entirely secure in Android M. Being an open source platform, security is one of the highest concerns and Google hasn&apos;t forgotten this.&lt;/p&gt;
&lt;h3&gt;Virtual Account Number&lt;/h3&gt;
&lt;p&gt;A virtual account number is used the entire time to process the payment. This means that your actual card number is not known or used in the transaction itself. Android Pay provides users the flexibility and choice in choosing their payment methods. You can hook up any supportive banking app to Android Pay, existing credit or debit cards as well. They&apos;re even working with mobile carries such as Sprint, Verizon and T-Mobile. It works with any devices having NFC support.&lt;/p&gt;
&lt;h2&gt;5. Fingerprint Support&lt;/h2&gt;
&lt;p&gt;Honestly, I would&apos;ve flipped, hadn&apos;t Google announced this. We&apos;ve already seen Apple do this on their iPhones putting it to creative uses and its about time Google did with Android too. Your fingerprint can now be used to process payments, make purchases on the Play Store and even unlock your device! Any developer could use it within their apps to authenticate either a payment or process using the fingerprint APIs.&lt;/p&gt;
&lt;h2&gt;6. Power &amp;amp; Charging&lt;/h2&gt;
&lt;p&gt;Smartphones always faced the problem of not holding enough charge, and if you&apos;re a mobile data user, you&apos;d probably be tagging along a power brick all the time! With more features being added in, the gravity of power management went higher. Android M kept this in mind and came up with a solution for it.&lt;/p&gt;
&lt;h3&gt;Say hello to Doze!&lt;/h3&gt;
&lt;p&gt;Doze is your smart(er) power management solution in Android M. While the device is asleep it manages power smartly, putting the device on a standby mode, while still handling the high priority messages and notifications you receive. During a test, Android M Developer Preview was capable of lasting x2 times longer than the same device running Android Lollipop.&lt;/p&gt;
&lt;h2&gt;Other Features:&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./android-m/so-thats-M-744x418.png&quot; alt=&quot;so thats M&quot; /&gt;&lt;/p&gt;
&lt;p&gt;While those were definitely the highlights, Android M Developer Preview still had a few aces up its sleeve for the reveal. Smaller, yet significant.&lt;/p&gt;
&lt;h3&gt;New USB Type-C Standard&lt;/h3&gt;
&lt;p&gt;We&apos;ve seen this in Apple&apos;s new MacBook and we&apos;ve all talked a lot about how not many support it. Google is really pushing this forward with Android M for it to be the new standard. The new USB type allows for much faster charging of devices. Almost 3-5 times faster! You could either charge using the port, or use the phone itself as a charger for other supporting devices. &lt;strong&gt;Here comes my favourite feature:&lt;/strong&gt; The USB pin is finally flippable!&lt;/p&gt;
&lt;h4&gt;Improved Word Selection&lt;/h4&gt;
&lt;p&gt;Android M finally understood our need to copy paste certain text by letting us do just that, easier, faster and above all, more intuitively. Copying and selecting parts of texts is no longer frustrating and it also provides a hovering Tooltip letting us to select actions such as copy and paste.&lt;/p&gt;
&lt;h5&gt;Easier Sharing&lt;/h5&gt;
&lt;p&gt;While Android did promote sharing of content/ media across apps, it really was downright annoying to do so. For instance, I often share on WhatsApp to my circle of friends. Me having to scroll all the way down to choose WhatsApp, isn&apos;t always the easiest thing to do. Android M gives users easier sharing by providing options to share from apps which you use the most and with which you share more. It now shows you app suggestions accordingly. Neat!&lt;/p&gt;
&lt;h5&gt;Simplified Volume Controls&lt;/h5&gt;
&lt;p&gt;I don&apos;t know what&apos;s up with Android Lollipop&apos;s volume controls. I mean Material Design was great, I loved it. Was a delight to use, but man those volume controls... Cheers to the fact that Android M got that straight with simplified volume controls that are easier to use and actually make more sense compared to Lollipop!&lt;/p&gt;
&lt;hr /&gt;
&lt;h5&gt;&lt;strong&gt;Release date&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;Android M Developer Preview available today for Nexus 5, 6, 7, 9 and Player. Final version is due to launch in Q3, 2015.&lt;/p&gt;
</content:encoded></item><item><title>+1 Button with Google Play Services 7.3.0</title><link>https://blog.iamsuleiman.com/plus-1-button-with-google-play-services-7-3-0/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/plus-1-button-with-google-play-services-7-3-0/</guid><description>Here we&apos;ll look at adding Google&apos;s +1 button in your app. Yep, its that tiny little g +1 button that turns red when you click it. You might have notic</description><pubDate>Thu, 14 May 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Here we&apos;ll look at adding Google&apos;s +1 button in your app. Yep, its that tiny little g +1 button that turns red when you click it. You might have noticed it on the Play Store. Using the latest libraries, I&apos;ll show you how to include one real quick in your apps. So people can +1 directly from your app!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./plus-1-button-with-google-play-services-7-3-0/1-recommend-google.png&quot; alt=&quot;1-recommend-google&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Why do you need it?&lt;/h2&gt;
&lt;p&gt;If you&apos;re wondering why should you care about it? Here&apos;s &lt;a href=&quot;http://mashable.com/2012/02/21/google-plus-1-seo/&quot;&gt;Mashable&apos;s take on it&lt;/a&gt;. While it says it affects SEO of websites, the same is true for apps too. The more people +1 it, the more frequently its going to appear on other&apos;s Play Store home screens. While the Play Store allows you to +1, its better if people can do that comfortably from within your app!&lt;/p&gt;
&lt;h2&gt;Pre 7.3.0&lt;/h2&gt;
&lt;p&gt;The earlier versions needed us to use the &lt;em&gt;PlusClient&lt;/em&gt; class from Google Play Services library. Too bad that its now deprecated. In fact, that class isn&apos;t even available for use anymore. So how do you go about it then?&lt;/p&gt;
&lt;h2&gt;The GoogleApiClient&lt;/h2&gt;
&lt;p&gt;This class was introduced with the Google Play Services 7.3.0 update. After this you have to use this class mandatory. Using the &lt;em&gt;PlusClient&lt;/em&gt; will give you an error. The good news is that its relatively simple with the &lt;em&gt;GoogleApiClient&lt;/em&gt; class. We&apos;ll start off by adding the gradle dependency for it first. Add this to your app&apos;s &lt;em&gt;build.gradle&lt;/em&gt; file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dependencies {
    compile &apos;com.google.android.gms:play-services:7.3.0&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;The main entry point for Google Play services integration. GoogleApiClient is used with a variety of static methods. Some of these methods require that GoogleApiClient be connected, some will queue up calls before GoogleApiClient is connected; check the specific API documentation to determine whether you need to be connected. - &lt;a href=&quot;https://developer.android.com/reference/com/google/android/gms/common/api/GoogleApiClient.html&quot;&gt;developer.android.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Create the +1 button&lt;/h2&gt;
&lt;p&gt;We need to place the button in our layout first, before we do anything else.&lt;/p&gt;
&lt;p&gt;Note the &lt;em&gt;plus&lt;/em&gt; namespace used. At the minimum, the PlusOneButton widget needs two XML attributes defined. That being its size and the annotation. There are different sizes and annotations that you could use for your button. More on that &lt;a href=&quot;http://developer.android.com/reference/com/google/android/gms/plus/PlusOneButton.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PlusOneButton mPlusOneButton = (PlusOneButton) findViewById(R.id.plus_one_button);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;@Override
protected void onResume() {
    super.onResume();
    mPlusOneButton.initialize(&quot;YourAppUrlOnPlayStore&quot;, PLUS_ONE_REQUEST_CODE);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After hooking up our &lt;em&gt;PlusOneButton&lt;/em&gt; to its XML widget, we just need to initialize it. It takes 2 parameters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The URL you want (usually your app url on the Play Store) Goes like &quot;&lt;em&gt;&lt;a href=&quot;http://market.android.com/details?id=com.yourpackage.name&quot;&gt;http://market.android.com/details?id=com.yourpackage.name&lt;/a&gt;&quot;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Plus one request code &lt;code&gt;private static final int PLUS_ONE_REQUEST_CODE = 0;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;GoogleApiClient Builder&lt;/h2&gt;
&lt;p&gt;Using the &lt;a href=&quot;https://developer.android.com/reference/com/google/android/gms/common/api/GoogleApiClient.Builder.html&quot;&gt;GoogleApiClient.Builder&lt;/a&gt; we can quickly initialize whatever is needed for setup. The developer docs say that we need to call the connect() and disconnect() method in our onStart() and onStop() methods of our activities respectively, regardless of the state. Firstly, let&apos;s initialize the client.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this)
        .addApi(Plus.API)
        .addScope(Plus.SCOPE_PLUS_LOGIN)
        .useDefaultAccount()
        .build()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;em&gt;GoogleApiClient&lt;/em&gt; class allows us to use various Google services APIs. We need that of Google+ so we add its API here &lt;code&gt;.addApi(Plus.API)&lt;/code&gt;. Suppose you want to use Google Drive, then the parameter would be &lt;code&gt;Drive.API&lt;/code&gt;. Next we need to add the &lt;a href=&quot;https://developer.android.com/reference/com/google/android/gms/common/Scopes.html&quot;&gt;scope&lt;/a&gt;. This is the OAuth 2.0 scopes for use with Google Play services. It entails what part of the services you require. You can even use multiple APIs with each of their respective scopes together. Thirdly, we need to set the user account. the userDefaultAccount() lets the user pick his Google account (if he has multiple). Otherwise you could explicitly specify it using &lt;code&gt;.setAccountName(&quot;accountname@gmail.com&quot;)&lt;/code&gt;. However this is not recommended.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override
protected void onStart() {
    super.onStart();
    mGoogleApiClient.connect();
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt; @Override
    protected void onStop() {
        super.onStop();
        mGoogleApiClient.disconnect();
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally to handle the &lt;em&gt;GoogleApiClient&lt;/em&gt; connection in the &lt;em&gt;onStart()&lt;/em&gt; and &lt;em&gt;onStop()&lt;/em&gt; methods respectively. That&apos;s it! You can now try hitting the +1 button in your app, and it will turn red! You can take this further with connection callbacks or click listeners informing the users with a Toast like &quot;&lt;strong&gt;You +1&apos;d this!&lt;/strong&gt;&quot;. Completely up to you!&lt;/p&gt;
</content:encoded></item><item><title>DIY Floating Action Button Part 2</title><link>https://blog.iamsuleiman.com/diy-floating-action-button-part-2/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/diy-floating-action-button-part-2/</guid><description>In this post, I&apos;ll show you how to make your Floating Action Button behave as it should on Lollipop devices. Elevation and ripple effects is what we&apos;l</description><pubDate>Fri, 08 May 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In this post, I&apos;ll show you how to make your Floating Action Button behave as it should on Lollipop devices. Elevation and ripple effects is what we&apos;ll be achieving. Part 1 of this post already covered how to make a Floating Action Button (FAB) and set it up for pre Lollipop. Check out &lt;a href=&quot;https://blog.iamsuleiman.com/diy-floating-action-button-part-1/&quot;&gt;part 1&lt;/a&gt; first if you haven&apos;t already. NOTE: There is now a native widget for a Floating Action Button (FAB). You can learn how to implement it from &lt;a href=&quot;https://blog.iamsuleiman.com/toolbar-animation-with-android-design-support-library/&quot;&gt;here&lt;/a&gt;.   In order to give those special treats for Lollipop devices, what we&apos;re going to do is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Remove the shadow beneath the FAB&lt;/li&gt;
&lt;li&gt;Replace the FAB selector with a selector&lt;/li&gt;
&lt;li&gt;Add a &apos;State List Animator&apos; to the FAB (elevates the FAB on touch)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/diy-floating-action-button-part-2/animation-responsiveinteraction-inkreactions-notouchripplepressandrelease_large_xhdpi.gif&quot; alt=&quot;&quot; title=&quot;ripple &amp;amp; elevation effect&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Removing the shadow&lt;/h2&gt;
&lt;p&gt;By removing what we&apos;ll do is, take out the shadow from the layout completely if the phone&apos;s running Lollipop. This can be done simply by using a Build check such as: &lt;code&gt;if (Build.VERSION.SDK_INT &amp;gt;= Build.VERSION_CODES.LOLLIPOP) {...}&lt;/code&gt; Now, if the build version is Lollipop and above, we&apos;ll remove the shadow using the &lt;em&gt;setVisibility&lt;/em&gt; method for our shadow like this: &lt;code&gt;fabShadow.setVisibility(View.GONE);&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;setVisibility() method&lt;/h3&gt;
&lt;p&gt;The method allows you 3 options for its parameter:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;View.VISIBLE&lt;/code&gt; - this is the default by which the view will be visible. You won&apos;t be using it unless you want to bring back an invisible view.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;View. INVISIBLE&lt;/code&gt; - exact opposite of the previous one (obviously, its in the name). The view remains in the layout, but cannot be seen&lt;/li&gt;
&lt;li&gt;&lt;code&gt;View.GONE&lt;/code&gt; - this takes the view OUT of the layout. It doesn&apos;t exist or reside in the layout.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/diy-floating-action-button-part-2/ezgif.com-gif-maker-1.gif&quot; alt=&quot;diy fab no shadow&quot; title=&quot;FAB without shadow&quot; /&gt;&lt;/p&gt;
&lt;p&gt;While both INVISIBLE and GONE don&apos;t display the view, INVISIBLE makes the view still exist, while GONE completely takes the view off the layout. We don&apos;t need the shadow beneath our FAB at all, which is why we&apos;ll use &lt;code&gt;View.GONE&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; if (Build.VERSION.SDK_INT &amp;gt;= Build.VERSION_CODES.LOLLIPOP) {
            fabShadow.setVisibility(View.GONE); 
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;&lt;a href=&quot;https://developer.android.com/reference/android/animation/StateListAnimator.html&quot;&gt;State List Animator&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is what will replace our removed shadow. This is nothing but a regular selector, but its items will be an &lt;a href=&quot;http://developer.android.com/reference/android/animation/ObjectAnimator.html&quot;&gt;objectAnimator&lt;/a&gt;. Using this we will alter the Z translation of our FAB which will elevate higher on click, and come back to its default elevation afterwards. This feature is part of the Lollipop SDK, and for it to be used properly, it must be placed in its proper folder. Create a new folder &lt;em&gt;res/&lt;strong&gt;animator&lt;/strong&gt;&lt;/em&gt;. This folder holds the XML animations exclusive to Lollipop. Create &lt;em&gt;fab_elevation_selector.XML&lt;/em&gt; under it. Our default Selector framework is this:&lt;/p&gt;
&lt;p&gt;For our pressed item, the &lt;em&gt;objectAnimator&lt;/em&gt; will change the FAB&apos;s &lt;em&gt;translationZ&lt;/em&gt; from 8 to 12dp. The default animator do the opposite. Change the &lt;em&gt;translationZ&lt;/em&gt; from 12 to 8dp (bring it back to its original state).&lt;/p&gt;
&lt;p&gt;I&apos;ve chosen the default short animation time for the duration. Gives us a smooth enough elevation. Now we&apos;ve got to tell our FAB to use it. A state list selector is referenced differently than a regular background selector. Unlike its drawable or color which is changed on click, a state list selector changes its property (translationZ) here upon click. Add this line in your FAB&apos;s &lt;em&gt;ImageView&lt;/em&gt;: &lt;code&gt;android:stateListAnimator=&quot;@animator/fab_elevation_selector&quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/diy-floating-action-button-part-2/ezgif.com-gif-maker-2.gif&quot; alt=&quot;diy fab with shadow statelistanimator&quot; title=&quot;With stateListAnimator&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Notice how its referenced as &lt;em&gt;@animator&lt;/em&gt; instead of &lt;em&gt;@drawable&lt;/em&gt; or &lt;em&gt;@anim&lt;/em&gt;. While the property may read as a &lt;em&gt;stateListAnimator&lt;/em&gt;, the XML that it references is actually a &lt;em&gt;selector&lt;/em&gt; XML.&lt;/p&gt;
&lt;h2&gt;Ripple Effect&lt;/h2&gt;
&lt;p&gt;Personally, I love the &lt;a href=&quot;https://developer.android.com/reference/android/graphics/drawable/RippleDrawable.html&quot;&gt;ripple effect&lt;/a&gt;. A new XML tag dedicated solely to this effect has been introduced since the advent of Lollipop &lt;code&gt;&amp;lt;ripple /&amp;gt;&lt;/code&gt;. It&apos;s pretty easy to use, but the only thing to keep in mind is it must reside in the &lt;em&gt;drawable-v21&lt;/em&gt; folder. So lets go about creating it. Create &lt;em&gt;res/drawable-v21/&lt;strong&gt;ripple_accent.xml&lt;/strong&gt;&lt;/em&gt; Why name it accent? Because my FAB uses the accent color, and so will its ripple!&lt;/p&gt;
&lt;p&gt;Yep, its as simple as that. The color belonging to the ripple tag, is the ripple color itself. The one in the item, bounds the ripple to a shape and gives it a base color. Not including the &lt;em&gt;item&lt;/em&gt; would give us a ripple on a transparent FAB! With that done, we just have to change the background selector for our FAB (&lt;em&gt;ImageView).&lt;/em&gt; Remember that we&apos;ve already set a background selector in &lt;a href=&quot;https://blog.iamsuleiman.com/diy-floating-action-button-part-1/&quot;&gt;Part 1&lt;/a&gt;. This is the one the FAB will use by default. For Lollipop, we need to tell it to use the ripple selector instead. We can do this simply by adding a line to our already existing Build check:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (Build.VERSION.SDK_INT &amp;gt;= Build.VERSION_CODES.LOLLIPOP) {
            fabShadow.setVisibility(View.GONE);
            fabBtn.setBackground(getDrawable(R.drawable.ripple_accent));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/diy-floating-action-button-part-2/ezgif.com-gif-maker-3.gif&quot; alt=&quot;diy fab ripple&quot; title=&quot;FAB with ripple&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Well, maybe the ripple may seem to subtle for you. But if you ask me, its already a bit heavy on the animations and a more prominent ripple would be overkill. Though feel free to alter the ripple if you wish via its XML. :-) You can head over to my &lt;a href=&quot;https://github.com/Suleiman19/Android-Material-Design-for-pre-Lollipop/tree/master/MaterialSample/app/src/main&quot;&gt;GitHub repository&lt;/a&gt; to check out the code samples.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;That&apos;s all there is to it! All we&apos;ve done is, hide our &apos;fake&apos; shadow drawable and replaced it with a &lt;em&gt;stateListAnimator&lt;/em&gt; that adds a shadow via elevation. Then replace the background selector to a ripple drawable. IMAGE CREDITS (card ripple gif) : &lt;a href=&quot;http://android-developers.blogspot.com/2014/10/implementing-material-design-in-your.html&quot;&gt;android-developers.blogspot.com&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Create a Material Color Palette in NO time</title><link>https://blog.iamsuleiman.com/create-a-material-color-palette-in-no-time/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/create-a-material-color-palette-in-no-time/</guid><description>If you&apos;re familiar with the new theme setup in Android since AppCompat v21, you&apos;ll need to define 3 colors from the start. That being your _colorPrima</description><pubDate>Mon, 04 May 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you&apos;re familiar with the new theme setup in Android since AppCompat v21, you&apos;ll need to define 3 colors from the start. That being your &lt;em&gt;colorPrimary, colorPrimaryDark&lt;/em&gt; and &lt;em&gt;accent&lt;/em&gt;. However I&apos;m pretty sure JUST those 3 isn&apos;t enough for your robust app and to add to it, deciding on colors and how it would look is no ordinary feat (at least for me). There are a lot of online resources that give us a visual palette to pick from. I&apos;ll point you to one that gets the work done in just 2 clicks!&lt;/p&gt;
&lt;h2&gt;Google&apos;s Material Color Palette&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./create-a-material-color-palette-in-no-time/google-material-color-palette-e1430729235593-744x424.png&quot; alt=&quot;google material color palette&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Personally, this is where I&apos;d go ALWAYS, to find myself some material colors. They have an exhaustive list of all the Material Design colors, complete with darker tones and accents. Copy pasting the HEX codes into my projects as and when required seemed intuitive at the time. They even let you download the entire color swatches as a zip.&lt;/p&gt;
&lt;h2&gt;&lt;a href=&quot;http://www.materialpalette.com/&quot;&gt;materialpalette.com&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./create-a-material-color-palette-in-no-time/materialpalette-744x418.png&quot; alt=&quot;materialpalette&quot; /&gt;&lt;/p&gt;
&lt;p&gt;If you&apos;ve never come across this website, then let&apos;s just say that, I&apos;d literally force you to use this instead. Why, you ask? Primarily because, in just two clicks, you&apos;ve got yourself an entire color palette ready for your theme, along with a preview! It&apos;s created by the same guy who runs &lt;a href=&quot;https://www.materialup.com/&quot;&gt;MaterialUp&lt;/a&gt;, Matt Aussaguel. You first pick your primary color and then your secondary. That&apos;s all you have to do. Sit back and watch the website generate a complete robust palette inclusive of your darker primary tone, text colors and lighter accent tone complete with a neat interactive preview on top. They make it even more convenient by allowing you to download it in different formats like XML, CSS, SASS, LESS, etc. If it&apos;s for your app, you can download the XML file and use it in your app. It works right out of the box!&lt;/p&gt;
&lt;h3&gt;Highlights:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Simplified palette only showing color primaries&lt;/li&gt;
&lt;li&gt;Choosing a primary and accent color is the only effort on your part&lt;/li&gt;
&lt;li&gt;Generates a complete, robust palette&lt;/li&gt;
&lt;li&gt;Live preview of the palette in use&lt;/li&gt;
&lt;li&gt;Readily downloadable in various formats&lt;/li&gt;
&lt;li&gt;Single click to copy color HEX code&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ever since I&apos;ve come across this website, it has been my go to place for some Material Design colors. You should give it a shot too!&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Know of something better? Drop &apos;em in the comments below.&lt;/p&gt;
</content:encoded></item><item><title>DIY Floating Action Button Part 1</title><link>https://blog.iamsuleiman.com/diy-floating-action-button-part-1/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/diy-floating-action-button-part-1/</guid><description>If you&apos;ve gone through my Implement a Floating Action Button(https://blog.iamsuleiman.com/implement-floating-action-button-part-1/) post, it shows you</description><pubDate>Sat, 02 May 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you&apos;ve gone through my &lt;a href=&quot;https://blog.iamsuleiman.com/implement-floating-action-button-part-1/&quot;&gt;Implement a Floating Action Button&lt;/a&gt; post, it shows you how to setup a neat FAB by using a library with relatively minimal effort. This post is for those who would like to avoid using one (like me) and make your own instead. I&apos;ll show you how to make a FAB very easily using XML only. I&apos;ll first show you how to imitate one for pre Lollipop, and then how we can tweak that to give an authentic experience on Lollipop devices exclusively in &lt;a href=&quot;https://blog.iamsuleiman.com/diy-floating-action-button-part-2/&quot;&gt;part 2&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Pre Lollipop&lt;/h2&gt;
&lt;p&gt;Now there are a couple of DIY methods:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Make a custom view component by extending &lt;em&gt;ImageButton&lt;/em&gt; class. For example in &lt;a href=&quot;http://github.com/futuresimple/android-floating-action-button/blob/master/library/src/main/java/com/getbase/floatingactionbutton/FloatingActionButton.java&quot;&gt;futuresimple&apos;s library&lt;/a&gt;, you can see how he&apos;s done it.&lt;/li&gt;
&lt;li&gt;Simple XML method with a circle drawable to your &lt;em&gt;ImageButton&lt;/em&gt; and add a shadow drawable below it.&lt;/li&gt;
&lt;li&gt;Create a &lt;em&gt;layer-list&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Personally, I prefer the second approach because I like to keep it simple and stick to XML for my UI as much as possible.&lt;/p&gt;
&lt;h3&gt;The Approach&lt;/h3&gt;
&lt;p&gt;What we&apos;ll be doing is similar to what we&apos;ve done for our Toolbar. Which is create the layout in a separate XML file then reference it in our mail layout using the &lt;code&gt;&amp;lt;include /&amp;gt;&lt;/code&gt; tag. We&apos;ll create an &lt;em&gt;ImageButton&lt;/em&gt; which serves as the main FAB layout. Add a &lt;em&gt;View&lt;/em&gt; below it for its shadow via a drawable. All this will be wrapped within a &lt;em&gt;FrameLayout,&lt;/em&gt; finally to be referenced in our main layout.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;My Floating Action Button&lt;/h3&gt;
&lt;p&gt;Create a new layout &lt;em&gt;res/layout/&lt;strong&gt;myfab.xml&lt;/strong&gt;&lt;/em&gt;.  The root element here is a &lt;em&gt;FrameLayout.&lt;/em&gt; The general layout for our FAB is this:&lt;/p&gt;
&lt;p&gt;If you&apos;re wondering why the shadow view is ABOVE the FAB while it actually must be BELOW, the thing is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;in a FrameLayout, the z-index is defined by the order in which the items are added&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So whatever place above, is drawn first. Our shadow will be rendered first, while our FAB will come next, overlapping the shadow.&lt;/p&gt;
&lt;h4&gt;Positioning the FAB&lt;/h4&gt;
&lt;p&gt;Unless, you&apos;re not familiar with the guidelines for a Floating Action Button, it says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The floating action button should be placed 16dp minimum from the edge on mobile and 24dp minimum on tablet/desktop.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Since our &lt;em&gt;FrameLayout&lt;/em&gt; will be holding the entire FAB layout, we&apos;ll start off by positioning it as per the guidelines. Position it at the screen&apos;s bottom right via &lt;code&gt;layout_gravity&lt;/code&gt; with a 16dp margin.&lt;/p&gt;
&lt;p&gt;The frame&apos;s width and height will be set to &lt;em&gt;100dp&lt;/em&gt; because we need some spacing around our FAB for the shadows. You can also notice that I&apos;ve not set the &lt;em&gt;16dp&lt;/em&gt; margins as specified by the guidelines. Why? Some simple math.&lt;/p&gt;
&lt;h5&gt;Calculation&lt;/h5&gt;
&lt;p&gt;FAB Size: &lt;strong&gt;56dp&lt;/strong&gt; FAB Shadow (to be defined): &lt;strong&gt;80dp&lt;/strong&gt; Frame: &lt;strong&gt;100dp&lt;/strong&gt; Now, our layouts within the Frame are centered within. So anything within 100dp can be contained within comfortably. &lt;strong&gt;100&lt;/strong&gt; (frame) - &lt;strong&gt;16&lt;/strong&gt; (margins) = &lt;strong&gt;84dp&lt;/strong&gt; (remaining) &lt;strong&gt;80dp&lt;/strong&gt; is taken up by the shadow (FAB included). So that&apos;s &lt;strong&gt;4dp&lt;/strong&gt; extra remaining in our Frame! This will be useful for Lollipop&apos;s elevation property, which we will be using to &quot;elevate&quot; the FAB upon click in the next part. We do not want our shadows do be clipped off due to lack of spacing. Now THAT would be ugly! I&apos;m sure we can allow ourselves a few dps of freedom for our FAB to float comfortably. Unless you want to strictly adhere to the guidelines, then simply alter the FrameLayout&apos;s dimensions as you see fit.&lt;/p&gt;
&lt;h4&gt;FAB Layout&lt;/h4&gt;
&lt;p&gt;We&apos;ll leave the &lt;em&gt;View&lt;/em&gt; for now, and dive straight into our &lt;em&gt;ImageView&lt;/em&gt; which is essentially our FAB.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./diy-floating-action-button-part-1/layout-2015-05-02-214407-171x300.png&quot; alt=&quot;FAB without background&quot; title=&quot;FAB without background&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The dimensions are the recommended size for a regular FAB, centered in our &lt;em&gt;FrameLayout&lt;/em&gt;. The &lt;em&gt;src&lt;/em&gt; is nothing but your FAB icon, whatever you want to keep. The &lt;em&gt;background&lt;/em&gt; attribute is what will define our FAB&apos;s shape, color and its click &lt;a href=&quot;http://developer.android.com/guide/topics/resources/drawable-resource.html#StateList&quot;&gt;selector&lt;/a&gt; as well.&lt;/p&gt;
&lt;h5&gt;FAB Selector&lt;/h5&gt;
&lt;p&gt;This is our basic selector. The first two are self-explanatory, that being the pressed and focused states for our FAB respectively. The last &lt;em&gt;item&lt;/em&gt; is the default layout our FAB will use when not responding to any touch events.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./diy-floating-action-button-part-1/layout-2015-05-02-214510-171x300.png&quot; alt=&quot;layout-2015-05-02-214510&quot; title=&quot;With ImageView background&quot; /&gt;&lt;/p&gt;
&lt;p&gt;We essentially need to define a circular shape for our FAB, its color (accent) and its color change (darker tone) upon touch for visual feedback. Within each &lt;em&gt;item&lt;/em&gt; tag, we&apos;ll start by setting its shape and color.&lt;/p&gt;
&lt;p&gt;The color will only be different for the last &lt;em&gt;item&lt;/em&gt; which is our default. The first two hold the pressed state for our FAB. Now you needn&apos;t worry that we&apos;ve not set any size for it because this will be defined by the &lt;em&gt;ImageView&lt;/em&gt; that references the selector. Finally, your selector should look like this:&lt;/p&gt;
&lt;h4&gt;FAB Shadow View&lt;/h4&gt;
&lt;p&gt;I&apos;m using a custom drawable png for my shadow here, so its dimensions should definitely be higher so that it can be visible behind the FAB. Now I&apos;ve found &lt;em&gt;80dp&lt;/em&gt; to be a good value that works for me. Feel free to adjust as you see fit.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./diy-floating-action-button-part-1/fab_shadow.png&quot; alt=&quot;fab_shadow.png&quot; title=&quot;fab_shadow.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I found a neat shadow drawable being used in a &lt;a href=&quot;https://github.com/makovkastar/FloatingActionButton&quot;&gt;Floating Action Button library by makovkastar&lt;/a&gt;. It&apos;s what I&apos;ve used for my FAB and from trial and error I can say for sure that compared to those layer list shadows, this one looks best by far. There are drawable pngs for all densities. Grab the zipped file &lt;a href=&quot;https://drive.google.com/uc?export=download&amp;amp;id=0BwdlpxsQ4WDCd19Kb2lYc2ljdVE&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Putting it together&lt;/h3&gt;
&lt;p&gt;Until now, what we&apos;ve done is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Created a separate XML for our Floating Action Button&lt;/li&gt;
&lt;li&gt;Added the &lt;em&gt;ImageView&lt;/em&gt; for our FAB.&lt;/li&gt;
&lt;li&gt;Referenced a selector for the &lt;em&gt;ImageView&lt;/em&gt; that defines shape &amp;amp; color&lt;/li&gt;
&lt;li&gt;Added a &lt;em&gt;View&lt;/em&gt; above the FAB layout for the shadow&lt;/li&gt;
&lt;li&gt;Referenced a shadow drawable png as a background for our &lt;em&gt;View&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally, we add our fab layout to our main activity layout file, just like we do for a Toolbar. &lt;code&gt;&amp;lt;include layout=&quot;@layout/myfab&quot; /&amp;gt;&lt;/code&gt; Make sure to add this as the LAST element in your XML as the FAB must be the top most view of your layout.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./diy-floating-action-button-part-1/layout-2015-05-02-214543-171x300.png&quot; alt=&quot;Final FAB with shadow&quot; title=&quot;Final FAB with shadow&quot; /&gt;&lt;/p&gt;
&lt;p&gt;You can check out my code sample over at &lt;a href=&quot;https://github.com/Suleiman19/Android-Material-Design-for-pre-Lollipop/blob/master/MaterialSample/app/src/main/res/layout/myfab.xml&quot;&gt;GitHub&lt;/a&gt;. For the sake of this post&apos;s length and simplicity, I&apos;ll be continuing the Lollipop part in my next post. To augment your FABs on Lollipop, head over to &lt;a href=&quot;https://blog.iamsuleiman.com/diy-floating-action-button-part-2/&quot;&gt;Part 2&lt;/a&gt; of this post!&lt;/p&gt;
</content:encoded></item><item><title>AppCompat v22.1 Support Library</title><link>https://blog.iamsuleiman.com/appcompat-v22-1-support-library/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/appcompat-v22-1-support-library/</guid><description>A lot of things have changed (for the better) with the support library. In AppCompat v22.1 various updates have been made to a lot of components as we</description><pubDate>Tue, 28 Apr 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A lot of things have changed (for the better) with the support library. In AppCompat v22.1 various updates have been made to a lot of components as well. Let&apos;s take a look at what&apos;s new.&lt;/p&gt;
&lt;h2&gt;What&apos;s new?&lt;/h2&gt;
&lt;h3&gt;&lt;strong&gt;AppCompat&lt;/strong&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;The AppCompat Support Library started with humble, but important beginnings: a single consistent Action Bar for all API 7 and higher devices. In &lt;a href=&quot;http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html&quot;&gt;revision 21&lt;/a&gt;, it took on new responsibility: bringing &lt;a href=&quot;http://developer.android.com/training/material/theme.html?utm_campaign=ASL221-415&amp;amp;utm_source=dac&amp;amp;utm_medium=blog#ColorPalette&quot;&gt;material color palette&lt;/a&gt;, widget tinting, Toolbar support, and more to all API 7+ devices. With that, the name &lt;code&gt;ActionBarActivity&lt;/code&gt; didn’t really cover the full scope of what it really did.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;AppCompatActivity&lt;/h4&gt;
&lt;p&gt;To be used now instead of &lt;em&gt;ActionBarActivity&lt;/em&gt; (deprecated).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Previously the only entry point into AppCompat was through the now deprecated ActionBarActivity class. Unfortunately this forced you into using a set Activity hierarchy which made things like using PreferenceActivity impossible. We’ve now extracted all of the internal stuff and exposed it as a single delegate API,&lt;a href=&quot;https://developer.android.com/reference/android/support/v7/app/AppCompatDelegate.html&quot;&gt;AppCompatDelegate&lt;/a&gt;. AppCompatDelegate can be created by any Android object which exposes a &lt;a href=&quot;https://developer.android.com/reference/android/view/Window.Callback.html&quot;&gt;Window.Callback&lt;/a&gt;, such as &lt;em&gt;any&lt;/em&gt; Activity or Dialog subclass. You create one via its static &lt;a href=&quot;https://developer.android.com/reference/android/support/v7/app/AppCompatDelegate.html#create(android.app.Activity,%20android.support.v7.app.AppCompatCallback)&quot;&gt;create()&lt;/a&gt; methods.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;AppCompatDialog&lt;/h4&gt;
&lt;p&gt;Finally Material styled dialogs! You can use this via the &lt;em&gt;AppCompatDialog&lt;/em&gt; class. For themes use &lt;code&gt;Theme.AppCompat.Dialog&lt;/code&gt; and for imports use &lt;code&gt;android.support.v7.app.AlertDialog&lt;/code&gt;. I&apos;m happy they finally included this which took quite a while! Now I can remove those third-party libraries that I use JUST for those dialogs.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./appcompat-v22-1-support-library/appcompat-v22.1-dialog-420x372.jpg&quot; alt=&quot;appcompat v22.1 dialog&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;Theming&lt;/h4&gt;
&lt;p&gt;Using AppCompat v21, we used to theme our Toolbars (and other views) using &lt;code&gt;app:theme&lt;/code&gt; . In AppCompat v22.1 you can theme using &lt;code&gt;android:theme&lt;/code&gt; . So you can now theme your toolbars like this:&lt;/p&gt;
&lt;p&gt;If you continue theming with the &lt;em&gt;app&lt;/em&gt; prefix, the downside is that theme inheritance will not work for layouts.&lt;/p&gt;
&lt;h4&gt;Widget Tinting&lt;/h4&gt;
&lt;p&gt;Tinting widgets are now available (plus a few new ones too!). This fixes the issue where widgets being used were not being tinted.&lt;/p&gt;
&lt;h2&gt;Support v4&lt;/h2&gt;
&lt;h3&gt;Drawable Tinting&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;Drawable drawable = ...;

// Wrap the drawable so that future tinting calls work
// on pre-v21 devices. Always use the returned drawable.
drawable = DrawableCompat.wrap(drawable);

// Set a tint
DrawableCompat.setTint(drawable, Color.RED);
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Palette&lt;/h4&gt;
&lt;p&gt;There&apos;s a new &lt;code&gt;Palette.Builder&lt;/code&gt; class.  You can then optionally change the maximum number of colors to generate and set the maximum size of the image to run Palette against before calling &lt;code&gt;generate()&lt;/code&gt; or &lt;code&gt;generateAsync()&lt;/code&gt; to retrieve the color Swatches. Plus there&apos;s a large performance increase since this update.&lt;/p&gt;
&lt;h4&gt;ColorUtils&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.android.com/reference/android/support/v4/graphics/ColorUtils.html&quot;&gt;ColorUtils&lt;/a&gt; has been moved out of Palette and into support-v4 as a public class. There&apos;s a lot of things to experiment with this!&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;For more details on implementation visit &lt;a href=&quot;https://chris.banes.me/2015/04/22/support-libraries-v22-1-0/&quot;&gt;Chris Banes blog&lt;/a&gt;.  Do check the &lt;a href=&quot;http://android-developers.blogspot.co.uk/2015/04/android-support-library-221.html&quot;&gt;developer&apos;s blog&lt;/a&gt; for a much more comprehensive take on AppCompat v22.1. Header image source: &lt;a href=&quot;http://lifehacker.com/&quot;&gt;lifehacker.com&lt;/a&gt; There seems to be a lot to look forward to in AppCompat v22.1.1 and get excited about. Are you?&lt;/p&gt;
</content:encoded></item><item><title>Why ActionBarActivity is deprecated?</title><link>https://blog.iamsuleiman.com/why-actionbaractivity-is-deprecated/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/why-actionbaractivity-is-deprecated/</guid><description>If you&apos;ve updated to the new Support Libraries (AppCompat 22.1.1), then you&apos;ve probably noticed by now that extending _ActionBarActivity_ for your Act</description><pubDate>Mon, 27 Apr 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;The Solution&lt;/h2&gt;
&lt;p&gt;If you&apos;ve updated to the new Support Libraries (AppCompat 22.1.1), then you&apos;ve probably noticed by now that extending &lt;em&gt;ActionBarActivity&lt;/em&gt; for your Activity classes is now deprecated. Woot!? Yes, after updating to the new AppCompat, it makes ActionBarActivity deprecated. You must now extend &lt;em&gt;AppCompatActivity&lt;/em&gt; instead. No sweat, everything else stays the same.&lt;/p&gt;
&lt;h2&gt;AppCompat v22.1.1&lt;/h2&gt;
&lt;p&gt;Apart from this, there are loads of other changes made in AppCompat 22.1.1. Know exactly what&apos;s going on over &lt;a href=&quot;https://blog.iamsuleiman.com/appcompat-v22-1-support-library/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Implement Floating Action Button - Part 2</title><link>https://blog.iamsuleiman.com/implement-floating-action-button-fab-part-2/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/implement-floating-action-button-fab-part-2/</guid><description>I&apos;d recommend going through Part 1 of the implementation first. It covers how you can quickly setup a Floating Action Button. Though if you feel you&apos;v</description><pubDate>Sat, 25 Apr 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;d recommend going through Part 1 of the implementation first. It covers how you can quickly setup a Floating Action Button. Though if you feel you&apos;ve already got that covered, feel free to proceed. In this part, I&apos;ll show you how we can add some neat animations to our Floating Action Button (FAB) such as the initial grow animation, as well as a Quick Return pattern (famously seen on the Google+ app).&lt;/p&gt;
&lt;h2&gt;Floating Action Button Animations&lt;/h2&gt;
&lt;p&gt;As per the design guidelines, the FAB must:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;hide upon scrolling down and reappear when scrolled up (known as the Quick Return Pattern)&lt;/li&gt;
&lt;li&gt;initially greet users with a &apos;grow&apos; animation upon entering app screen&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The quick return pattern can most commonly be found in the current Google+ app. Screen real estate is important especially on smaller devices. Upon scrolling, the toolbar and FAB translate to being hidden. This allows you to view the main scrollable content, distraction-free. When you scroll up, both views translate back up. For a better idea on what it is, watch it in action below: &lt;a href=&quot;http://www.youtube.com/watch?v=SxcvZ1qIyZ4&quot;&gt;Watch on YouTube&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Quick Return&lt;/h3&gt;
&lt;h4&gt;Custom ScrollListener&lt;/h4&gt;
&lt;p&gt;So first off, let&apos;s create the Quick Return pattern. It&apos;s better to sort and organize your project from the very beginning, so create a new package &lt;em&gt;utils&lt;/em&gt; under your main package &lt;em&gt;com.yourname.app&lt;/em&gt;. Now under the &lt;em&gt;utils&lt;/em&gt; package, create a new abstract class &lt;code&gt;MyRecyclerScroll&lt;/code&gt;&lt;em&gt;.&lt;/em&gt; This is going to extend &lt;code&gt;RecyclerView.OnScrollListener&lt;/code&gt;. Now its pretty obvious what extends class will do (judging from the name). Yep, you&apos;re right, listen to scroll events! Now the OnScrollListener provides us with 2 handy methods that we can use, such as the &lt;code&gt;onScrolled()&lt;/code&gt; and the &lt;code&gt;onScrollStateChanged()&lt;/code&gt; method. However, the method that we&apos;re interested in is the &lt;code&gt;onScrolled()&lt;/code&gt;&lt;em&gt;.&lt;/em&gt; So go ahead and implement that method.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public abstract class MyRecyclerScroll extends RecyclerView.OnScrollListener {
   
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        ...
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now why we made it an abstract class is because, we&apos;re going to create a custom scroll listener for our recycler view that detects the direction of scroll. Depending on that, we&apos;ll hide or show our FAB. We&apos;ll then hook it up to the fab in our &lt;em&gt;MainActivity.java&lt;/em&gt; and implement its methods to handle them.&lt;/p&gt;
&lt;h4&gt;The Approach&lt;/h4&gt;
&lt;p&gt;So before we dive into the all the messy code, let&apos;s analyse how the Quick Return Pattern works.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;When the user scrolls down, the FAB animates downward and gets hidden.&lt;/li&gt;
&lt;li&gt;The FAB remains hidden while the user scrolls down.&lt;/li&gt;
&lt;li&gt;If the FAB is not visible and user scrolls up, the FAB animates up and becomes visible.&lt;/li&gt;
&lt;li&gt;FAB continues to remain visible while the user scrolls up.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With that said, in order to achieve this we need to track just two things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The distance &amp;amp; direction of scroll&lt;/li&gt;
&lt;li&gt;Whether the FAB is visible&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let&apos;s start off by declaring those 2 variables that we need.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int scrollDist = 0;
boolean isVisible = true;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Initialy scroll distance will obviously be zero, hence its set to that. By default upon entrance the FAB will be visible and so the boolean is set to true.&lt;/p&gt;
&lt;h4&gt;onScrolled Method&lt;/h4&gt;
&lt;p&gt;Now in the &lt;code&gt;onScrolled()&lt;/code&gt; method, if we take a look at the last 2 parameters: &lt;code&gt;int dx, int dy&lt;/code&gt;. These are the horizontal and vertical scrolls respectively. We&apos;re only concerned with dy, which gives us a positive value on scrolling down, and negative value scrolling up. We need to record the scroll distance first, then do appropriate checks whether the FAB is visible and accordingly show or hide it. Also, in order to check if the scroll distance will suffice, add a new variable  &lt;code&gt;static final float MINIMUM = 25&lt;/code&gt;. This is the value against which we&apos;ll check our scroll distance. Unless the scroll distance not going to be greater than that, we won&apos;t bother to hide or show the FAB. It helps avoid weird stuttering with the FAB, when we scroll slightly in either direction.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);

        if (isVisible &amp;amp;&amp;amp; scrollDist &amp;gt; MINIMUM) {
            hide();
            scrollDist = 0;
            isVisible = false;
        }
        else if (!isVisible &amp;amp;&amp;amp; scrollDist &amp;lt; -MINIMUM) {
            show();
            scrollDist = 0;
            isVisible = true;
        }

        if ((isVisible &amp;amp;&amp;amp; dy &amp;gt; 0) || (!isVisible &amp;amp;&amp;amp; dy &amp;lt; 0)) {
            scrollDist += dy;
        }

    }
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Algorithm&lt;/h4&gt;
&lt;p&gt;Nothing scary up there. We&apos;re just handling 2 if conditions; hide FAB if visible when scrolling down, and show FAB if not visible when scrolling up.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We&apos;re first checking if FAB is visible and if the scroll(down) is above the minimum.&lt;/li&gt;
&lt;li&gt;If that&apos;s true then, hide FAB. Since it&apos;s not visible anymore, set its boolean and also reset scroll distance.&lt;/li&gt;
&lt;li&gt;We only need to record scroll distance upto which the FAB hides/ shows. Need not bother recording the ENTIRE scroll distance.&lt;/li&gt;
&lt;li&gt;Similarly, if the FAB is hidden, we&apos;ll call the &lt;em&gt;show()&lt;/em&gt; method.&lt;/li&gt;
&lt;li&gt;We&apos;re checking scroll distance against -MINIMUM because remember I said dy gives a negative value on scrolling up. Hence we must compare it against negativ MINIMUM.&lt;/li&gt;
&lt;li&gt;Finally, the two OR conditions are  whether the user scrolls up or down, we&apos;ll just count the scroll distance.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Below this method, add 2 abstract methods.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public abstract void show();
public abstract void hide();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&apos;ll be using these methods in our MainActivity to handle our FAB.&lt;/p&gt;
&lt;h4&gt;Attaching to the Activity&lt;/h4&gt;
&lt;p&gt;Our custom ScrollListener is now complete. All we need to do is attach it to our MainActivity and implement its abstract methods &lt;em&gt;show()&lt;/em&gt; &amp;amp; &lt;em&gt;hide()&lt;/em&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;...
recyclerView.setOnScrollListener(new MyRecyclerScroll() {
           @Override
           public void show() {
               fab.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2)).start();
           }

           @Override
           public void hide() {
               fab.animate().translationY(fab.getHeight() + fabMargin).setInterpolator(new AccelerateInterpolator(2)).start();
           }
       });
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&apos;re simply attaching our custom ScrollListener &apos;MyRecyclerScroll&apos; as the ScrollListener for our RecyclerView. Upon doing so, we implement the 2 abstract methods. For the show method, we handle the show animation for the FAB. The &lt;em&gt;translationY&lt;/em&gt; distance is 0 because we want the FAB to come back to its original position. For hide method, we obviously hide the FAB. It&apos;s translation distance will be the FAB height (56dp) + its margin (16dp). This is the distance the FAB is required to move off screen. You could play around with different Interpolators and their timings no issues, but I&apos;ve found these to work just fine for me. Now go ahead and run your app. You can see our FAB animate quite nicely.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/implement-floating-action-button-fab-part-2/ezgif.com-crop-compressor.gif&quot; alt=&quot;fab quick return animation&quot; /&gt; *&lt;/p&gt;
&lt;h3&gt;Grow Animation&lt;/h3&gt;
&lt;p&gt;Next, we&apos;ll implement a grow animation for our Floating Action Button.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The floating action button animates onto the screen as an expanding piece of material, by default. The icon within it may be animated. - &lt;a href=&quot;http://www.google.co.in/design/spec/components/buttons-floating-action-button.html#buttons-floating-action-button-floating-action-button&quot;&gt;source&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This one&apos;s relatively easy to implement. All that we&apos;re going to do is create an XML scaling animation that grows our FAB from 0 to its original dimensions. We will then reference that animation in our Activity and attach it to our FAB.&lt;/p&gt;
&lt;h4&gt;The XML&lt;/h4&gt;
&lt;p&gt;Start by creating a new folder called &lt;em&gt;anim&lt;/em&gt; under your &lt;em&gt;res&lt;/em&gt; folder. Create a new XML file for a &lt;em&gt;scale&lt;/em&gt; animation and name it &lt;em&gt;simple_grow.xml&lt;/em&gt;. So our path should be like &lt;em&gt;res/anim/simple_grow.xml&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The X &amp;amp; Y to and from scale parameters are essential. We tell the animation that we need to start from 0 scale, which is no dimensions ( so you cant see it) and then scale the X &amp;amp; Y to 1.0 (maximum scale) so that we can see the FAB. 700 is a nice duration for the animation (which I&apos;ve fixed at after a lot of trial). We need to give the animation some time to run and for the user to admire it.The pivot X &amp;amp; Y say that we want to scale it from the center. Without defining these two, the animation will scale from the top left by default. Lastly, we set a Decelerate Interpolator so that it looks nice. It lets the scale ease the animation towards the end.&lt;/p&gt;
&lt;p&gt;If you&apos;re interested in knowing more about Interpolators, you can give &lt;a href=&quot;http://cogitolearning.co.uk/?p=1078&quot;&gt;this&lt;/a&gt; a read, or watch it live below. Have fun experimenting with different Interpolators to achieve different effects!&lt;/p&gt;
&lt;h4&gt;Add animation to the FAB&lt;/h4&gt;
&lt;p&gt;Open the &lt;em&gt;MainActivity.xml&lt;/em&gt; and define the animation before we set our content view using  &lt;code&gt;Animation animation = AnimationUtils.loadAnimation(this, R.anim.simple_grow);&lt;/code&gt; Then after we&apos;ve referenced our fab from the XML, we simply set the animation to the FAB with  &lt;code&gt;fab.startAnimation(animation);&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Animation animation = AnimationUtils.loadAnimation(this, R.anim.simple_grow);
        ...
        fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.startAnimation(animation);
       
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Whatever you&apos;ve got running in your &lt;code&gt;onCreate()&lt;/code&gt; method, make sure you start the FAB animation at the end. Making it start too early would cause to animation to skip by the time the user gets to see. So make it run towards the end of your &lt;code&gt;onCreate()&lt;/code&gt;. Watch the video below to see how it finally looks like. &lt;a href=&quot;http://www.youtube.com/watch?v=TlYHpltbfxI&quot;&gt;Watch on YouTube&lt;/a&gt; With this, we&apos;re done. Cheers! We&apos;ve got a nice little growing animation that greets the user upon entering the app, and then the FAB translates nicely when the user scrolls up and down the list. &lt;a href=&quot;https://drive.google.com/uc?export=download&amp;amp;id=0BwdlpxsQ4WDCLUFPT3FBTWd5VFE&quot;&gt;Download the project&lt;/a&gt; or head over to my &lt;a href=&quot;https://github.com/Suleiman19/Android-Material-Design-for-pre-Lollipop/tree/master/MaterialSample/app/src/main&quot;&gt;GitHub repo&lt;/a&gt; to check out the animation code sample.&lt;/p&gt;
</content:encoded></item><item><title>Implement Floating Action Button - Part 1</title><link>https://blog.iamsuleiman.com/implement-floating-action-button-part-1/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/implement-floating-action-button-part-1/</guid><description>A new component introduced in Material Design is the Floating Action Button. It is an elevated circular view that floats above the UI in the bottom ri</description><pubDate>Mon, 20 Apr 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;What is a Floating Action Button?&lt;/h2&gt;
&lt;p&gt;A new component introduced in Material Design is the Floating Action Button. It is an elevated circular view that floats above the UI in the bottom right. Its usually noted by its distinct visual that emphasizes that screen&apos;s most important action.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./implement-floating-action-button-part-1/components_buttons_usage1-e1429491758281.png&quot; alt=&quot;components_buttons_usage1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I&apos;ll show you how we can quickly set up one that works on devices preceding Lollipop in this relatively simple tutorial.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Floating action buttons are used for a promoted action. They are distinguished by a circled icon floating above the UI and have motion behaviors that include morphing, launching, and a transferring anchor point. - Material Design &lt;a href=&quot;http://www.google.com/design/spec/components/buttons-floating-action-button.html#buttons-floating-action-button-floating-action-button&quot;&gt;source&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./implement-floating-action-button-part-1/unnamed-169x300.png&quot; alt=&quot;android gmail lollipop material design&quot; title=&quot;FAB in Gmail&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Set Up&lt;/h2&gt;
&lt;p&gt;Create new project in Android Studio and  set minSdkLevel to 14 (Icecream Sandwich). Why Icecream Sandwich you ask? Well, by using API Level 14 and above you&apos;re targeting more than 90% of the Android devices. I&apos;m sure you&apos;d agree with me when I say that its worth the sacrifice. We should be focusing on delivering quality for current users rather than sacrificing for supporting very old devices. The world&apos;s moving forward, so should you and your apps.&lt;/p&gt;
&lt;h2&gt;Quick implementation with library&lt;/h2&gt;
&lt;p&gt;Let&apos;s start off by adding a gradle dependency for a wonderful &lt;a href=&quot;https://github.com/futuresimple/android-floating-action-button&quot;&gt;Floating Action Button library created by futuresimple&lt;/a&gt;. We&apos;ll be implementing our Floating Action Button with this. Not too fancy, but its just what we need.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dependencies {
    compile &apos;com.getbase:floatingactionbutton:1.9.0&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Why use a library?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Avoid building from the ground up&lt;/li&gt;
&lt;li&gt;Can quickly set up what we need with minimal effort&lt;/li&gt;
&lt;li&gt;Saves LOADS of time and frustration&lt;/li&gt;
&lt;li&gt;Most of all, easy to use!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With this library implementation, we immediately can create a FAB like any other normal UI widget in XML. We can also set its properties easily. With the complex part of the UI code handled by the library, that leaves us to focus on building our actual app faster. As a rule of thumb, if you&apos;ve found a good library that&apos;s not too heavy on file size and suits your purposes well. Then I&apos;d suggest you go for it. Why do you want to build something from scratch, when the exact same thing already exists, available for use? Enough talk, let&apos;s get to adding a FAB to our layout.&lt;/p&gt;
&lt;h2&gt;Adding FAB to the layout&lt;/h2&gt;
&lt;p&gt;Open up your &lt;em&gt;activity_main.xml&lt;/em&gt; under &lt;em&gt;res/layout&lt;/em&gt; and add this to it.&lt;/p&gt;
&lt;p&gt;I&apos;m wrapping my FAB within a RelativeLayout, hence why you see the alignParent properties used. Suppose you wrap it within a FrameLayout, use &lt;code&gt;android:layout_gravity=&quot;bottom|right&quot;&lt;/code&gt;instead. The properties with the &lt;em&gt;fab&lt;/em&gt; namespace belong to the library. According to Material Design guidelines, the FAB must be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;positioned at the bottom right of screen&lt;/li&gt;
&lt;li&gt;elevated higher that other views, such that it appears to be floating above them&lt;/li&gt;
&lt;li&gt;maintain a margin of 16dp from the bottom and right edges of the screen&lt;/li&gt;
&lt;li&gt;have a size of either 56dp (default) or 40dp (mini)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Don&apos;t worry if your Preview doesn&apos;t show you much of a&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./implement-floating-action-button-part-1/fab-layout-171x300.png&quot; alt=&quot;fab floating action button layout&quot; /&gt;&lt;/p&gt;
&lt;p&gt;FAB, just compile and run. The emulator should show you what you expect to see. We&apos;ve now got a nicely positioned FAB at the bottom right. Note that the only thing we&apos;ve done is add the fab to our layout and we&apos;ve already got all of its visual aspects set such as the shadow mimicking elevation, thanks to the library. For the sake of this tutorial whose purpose is to show you how a fab works, I will use a simple &lt;em&gt;RecyclerView&lt;/em&gt; that holds a list (for scrolling). Now if some of you have issues with your fab not changing color on tap, or not detecting your taps entirely, its mostly a layout ordering issue. Note that within my &lt;em&gt;RelativeLayout,&lt;/em&gt; I have a &lt;em&gt;RecyclerView&lt;/em&gt; that holds some dummy data for a list. Now the fab layout must be below the &lt;em&gt;RecyclerView&lt;/em&gt; for it to work.&lt;/p&gt;
&lt;h2&gt;Click Listener&lt;/h2&gt;
&lt;p&gt;Go to your &lt;em&gt;MainActivity.xml&lt;/em&gt; and reference the FAB from XML. It is setup like any other normal click listener.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FloatingActionButton fab;

@Override
    protected void onCreate(Bundle savedInstanceState) {
    ...
        fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               // Your FAB click action here...
               Toast.makeText(getBaseContext(), &quot;FAB Clicked&quot;, Toast.LENGTH_SHORT).show();
            }
        });
...

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The final output will be like this. A Floating Action Button positioned correctly, that reacts on click events.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.iamsuleiman.com/assets/images/implement-floating-action-button-part-1/fab-part1-final.gif&quot; alt=&quot;floating action bar click&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Sum it up&lt;/h2&gt;
&lt;p&gt;We&apos;ve seen how to setup a Floating Action Button quickly using a library. We then added it to our layout and defined its custom properties. We&apos;ve also seen how to handle it&apos;s click events with a simple Toast message. Check out &lt;a href=&quot;https://blog.iamsuleiman.com/implement-floating-action-button-fab-part-2/&quot;&gt;part 2&lt;/a&gt; where I&apos;ll be showing you how to add some neat animations to our FAB!&lt;/p&gt;
</content:encoded></item><item><title>Toolbar Height in Landscape mode (FIX)</title><link>https://blog.iamsuleiman.com/toolbar-height-in-landscape-mode-fix/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/toolbar-height-in-landscape-mode-fix/</guid><description>Fix for the Android Toolbar height issue in landscape mode where the title is not vertically centered.</description><pubDate>Sun, 19 Apr 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Toolbar height issue&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./toolbar-height-in-landscape-mode-fix/Screenshot_2015-04-19-11-32-36-e1429440058830.png&quot; alt=&quot;Screenshot_2015-04-19-11-32-36&quot; /&gt;&lt;/p&gt;
&lt;p&gt;If you&apos;ve noticed by now, the Toolbar height by default when compared in normal and landscape mode, is different. There seems to be extra padding at the bottom where the Toolbar title is not vertically centered.&lt;/p&gt;
&lt;p&gt;This issue is all the more prominent when you attach a scrollable view. The views scrolls slightly into the toolbar.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./toolbar-height-in-landscape-mode-fix/Screenshot_2015-04-19-11-32-49-e1429440146764.png&quot; alt=&quot;Screenshot_2015-04-19-11-32-49&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;The solution&lt;/h2&gt;
&lt;p&gt;Now, the fix for this is relatively simple. We need to change our toolbar height  to what our minimum height is. Open &lt;em&gt;toolbar.xml,&lt;/em&gt; remove the &lt;code&gt;minHeight&lt;/code&gt; attribute and change the &lt;code&gt;layout_height&lt;/code&gt; to &lt;code&gt;?attr/actionBarSize&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;So your initial Toolbar layout would be like this:&lt;/p&gt;
&lt;p&gt;That would be changed to:&lt;/p&gt;
&lt;p&gt;Here is a deliberate side by side comparison for you to see the difference between how the Toolbar height WAS in landscape, and how its supposed to be on the right (after we fixed it).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./toolbar-height-in-landscape-mode-fix/Screenshot_2015-04-19-11-32-49-e1429440146764.png&quot; alt=&quot;Toolbar in landscape before the fix, title not vertically centered&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./toolbar-height-in-landscape-mode-fix/Screenshot_2015-04-19-11-33-53-e1429440422223.png&quot; alt=&quot;Toolbar in landscape after the fix, title vertically centered&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So my suggestion is to stick to using the &lt;code&gt;android:layout_height&lt;/code&gt; attribute for your Toolbar layout height and avoid using &lt;code&gt;app:minHeight&lt;/code&gt;  especially when dealing with landscape mode and scrollable views.&lt;/p&gt;
</content:encoded></item><item><title>Why app design is important</title><link>https://blog.iamsuleiman.com/why-app-design-is-important/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/why-app-design-is-important/</guid><description>As developers, we code our apps stuffing them with every possible feature we thought of it to have. It originated with one great idea, and we thought </description><pubDate>Tue, 14 Apr 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As developers, we code our apps stuffing them with every possible feature we thought of it to have. It originated with one great idea, and we thought of numerous ways to better it by adding more &apos;cool&apos; features to it, overlooking app design. Finally when we&apos;ve made our apps, maybe put it on the Play Store, showed it off to our friends and others, we may begin to see that not everyone is as pleased to use your app like you do.&lt;/p&gt;
&lt;h2&gt;Users have options&lt;/h2&gt;
&lt;p&gt;Today, users are spoilt for choice. The &apos;great&apos; app idea you thought of is highly likely that it already would be existing, so if you plan on still going ahead with it, unless you have a strong reason as to why your app is better, no one&apos;s going to bother.&lt;/p&gt;
&lt;p&gt;Remember, the Play Store now has more than 1.4 million apps (&lt;a href=&quot;http://www.statista.com/statistics/266210/number-of-available-applications-in-the-google-play-store/&quot;&gt;source&lt;/a&gt;). With a count that huge, and so many options. You need to give them a reason to pick yours over others.&lt;/p&gt;
&lt;h2&gt;Q &amp;amp; A&lt;/h2&gt;
&lt;p&gt;Initially at start, we&apos;d ask ourselves, or at least you should have is &lt;em&gt;&quot;Why am I making this app?&quot;.&lt;/em&gt; It&apos;s answer would be something like &lt;em&gt;&quot;Because it has these A B C feature(s) that would help make people&apos;s X Y Z work easier&quot;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;With a Q&amp;amp;A like the one above, you&apos;ve pretty much got yourselves an idea for an app that would actually serve some purpose and cater to a niche group of people who would probably use that app.Maybe you&apos;ve even taken it a step further to scout the Play Store checking if anything similar already exists. If it doesn&apos;t, well, good for you! If not, then give users something that makes them want to use yours more than the other.&lt;/p&gt;
&lt;h2&gt;The users are not you&lt;/h2&gt;
&lt;p&gt;Gather some people you know, say your friends. Let everyone use the app. Don&apos;t tell them anything, do not guide them. Just let them learn the ropes on their own.&lt;/p&gt;
&lt;p&gt;While they&apos;re at it, observe how they use the app and check their reactions. &lt;em&gt;&quot;What does this do?&quot;, &quot;Where do I go from here?&quot;, &quot;What&apos;s happening now?&quot;.&lt;/em&gt; These are somethings that they&apos;re gonna ask you, and if its a lot of questions then you&apos;ve got some serious design issues.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&quot;Why don&apos;t they get it? It&apos;s so obvious and simple.&quot;&lt;/em&gt; To think those people were stupid and ignoring them would be your stupidity. YOU know because you made it, but not them and its your responsibility (via your app) to educate, inform and guide the users throughout.Its your creation so obviously you&apos;re in love with it, and I don&apos;t blame you. But why should others feel the same?&lt;/p&gt;
&lt;h2&gt;Simple yet effective&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;“I strive for two things in design: simplicity and clarity. Great design is born of those two things.” - Lindon Leader&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Stick to clean and distinct visual design. &lt;strong&gt;Less is more&lt;/strong&gt;. This is the current design trend and everyone is pushing towards it. Clean design helps make your actual content stand out and highlights the most important aspects in your app design.&lt;/p&gt;
&lt;p&gt;For instance, look closely how Google has slowly improved its Gmail app consistently. Over time, it has become more clean and simpler in design.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./why-app-design-is-important/gmail-for-android.png&quot; alt=&quot;Gmail for Android&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./why-app-design-is-important/gmail-old.png&quot; alt=&quot;Gmail older design&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./why-app-design-is-important/gmail-clean.png&quot; alt=&quot;Gmail clean design&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Focus on the user and all else will follow&quot;- &lt;a href=&quot;http://www.google.co.in/about/company/philosophy/&quot;&gt;Google&apos;s Design Philosophy&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;App design is important&lt;/h2&gt;
&lt;p&gt;It incorporates not only just the visual elements that occupy the screen, but app design also involves the users&apos; experience while using them. As developers its our responsibility to create those experiences for users that they remember and want to keep coming back to.&lt;/p&gt;
&lt;p&gt;Why are the top apps so popular? Take WhatsApp for example. Did you ever feel frustrated using it? Its purpose is instant messaging and it does just that. In fact it does it so well, people rely on it heavily due to its sheer convenience. When the user automatically sees and understands what to do, what does what and how to do it, without anyone telling them, that is good design.&lt;/p&gt;
&lt;p&gt;We have so many variations for a single app now, you need to make yours stand out. Go the extra mile for a strong emphasis in design that delights users. That&apos;s some great experience right there.&lt;/p&gt;
</content:encoded></item><item><title>Android Material Design: Getting Started with Lollipop</title><link>https://blog.iamsuleiman.com/android-material-design-tutorial/</link><guid isPermaLink="true">https://blog.iamsuleiman.com/android-material-design-tutorial/</guid><description>In this tutorial, I’ll show you how to implement Android Material Design for your apps running on pre Lollipop devices. Material Design is Google’s ne</description><pubDate>Sun, 12 Apr 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In this tutorial, I’ll show you how to implement Android Material Design for your apps running on pre Lollipop devices. Material Design is Google’s new design language for Android apps, replacing the previously used Holo theme.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A material metaphor is the unifying theory of a rationalized space and a system of motion. The material is grounded in tactile reality, inspired by the study of paper and ink, yet technologically advanced and open to imagination and magic. Read more about it &lt;a href=&quot;http://www.google.com/design/spec/material-design/introduction.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I will be using Android Studio 1.1 (you should too!). My gradle settings are (by default):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;compileSdkVersion 22&lt;/li&gt;
&lt;li&gt;buildToolsVersion 22.0.1&lt;/li&gt;
&lt;li&gt;minSdkVersion 9&lt;/li&gt;
&lt;li&gt;targetSdkVersion 22&lt;/li&gt;
&lt;li&gt;appcompat-v7:22.1.1&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; This new version of AppCompat released a lot of changes, so you might want to &lt;a href=&quot;https://chris.banes.me/2015/04/22/support-libraries-v22-1-0/&quot;&gt;read further&lt;/a&gt; what exactly is changed. If you want to implement Material Design for Tablets, you can get started &lt;a href=&quot;https://blog.iamsuleiman.com/material-design-for-tablets/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;strong&gt;Setting up the project&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Create a new Studio project with the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Check Phone and Tablet&lt;/li&gt;
&lt;li&gt;Minimum SDK: API 9&lt;/li&gt;
&lt;li&gt;Blank Activity template&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;You may immediately notice a new folder called &lt;strong&gt;mipmap&lt;/strong&gt;, instead of drawable density folders. Just remember that, mipmaps store your launcher icons. You can create the regular drawable folders as before and continue to use them. More on mipmaps &lt;a href=&quot;http://androidbycode.wordpress.com/2015/02/14/goodbye-launcher-drawables-hello-mipmaps/&quot;&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Check your &lt;em&gt;build.gradle&lt;/em&gt; file for the following dependency&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dependencies {
    compile com.android.support:appcompat-v7:22.0.+&quot;
    ...
 }
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;strong&gt;Set up theme&lt;/strong&gt;&lt;/h2&gt;
&lt;h3&gt;&lt;strong&gt;Brand Colors&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;The app requires you to define 3 colors for your brand identity:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;primary 500– main color of your app. Used in toolbar.&lt;/li&gt;
&lt;li&gt;primary 700– a darker tint of the primary color. Used for the status bar.&lt;/li&gt;
&lt;li&gt;accent–  different color, used in action buttons and components like sliders or switches.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can refer them from the &lt;a href=&quot;http://www.google.co.in/design/spec/style/color.html#color-color-palette&quot;&gt;official material color palette&lt;/a&gt; , or define your own.&lt;/p&gt;
&lt;p&gt;Go to &lt;em&gt;res/values&lt;/em&gt; and create &lt;em&gt;colors.xml&lt;/em&gt;. Here are my colors:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
#2196F3

#1976D2

#FF5252
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;strong&gt;Add colors to your theme&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Now that we’ve created the colors, we need to tell the theme to use them. Open your &lt;em&gt;styles.xml&lt;/em&gt; in &lt;em&gt;res/values&lt;/em&gt; and add the colors like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@color/colorPrimary
@color/colorPrimaryDark
@color/colorAccent
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;UPDATE: Since AppCompat v21.1.1, you need to make sure your themes inherit from &lt;code&gt;parent=&quot;Theme.AppCompat.Light.NoActionBar&quot;&lt;/code&gt;. Otherwise you&apos;ll get an error similar to the one &lt;a href=&quot;http://stackoverflow.com/questions/29790070/upgraded-to-appcompat-v22-1-0-and-now-getting-illegalargumentexception-appcompa&quot;&gt;over here at Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Theming for Lollipop&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;By default when creating your project, the parent theme in res/values/styles.xml would be &lt;em&gt;Theme.AppCompat.Light.DarkActionBar&lt;/em&gt;.  Using AppCompat on Lollipop devices, elevates the theme to the real Material theme. In other words, we will be inheriting the same theme.&lt;/p&gt;
&lt;p&gt;Creating a folder &lt;em&gt;res/values-v21&lt;/em&gt; and create &lt;em&gt;styles.xml&lt;/em&gt; under it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
      &amp;lt;item name=&quot;android:colorPrimary&quot;&amp;gt;@color/colorPrimary&amp;lt;/item&amp;gt;
      &amp;lt;item name=&quot;android:colorPrimaryDark&quot;&amp;gt;@color/colorPrimaryDark&amp;lt;/item&amp;gt;
      &amp;lt;item name=&quot;android:colorAccent&quot;&amp;gt;@color/colorAccent&amp;lt;/item&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice that the only difference between the styles.xml under values and values-v21 is the prefix &quot;android&quot;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;strong&gt;Hello Toolbar&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Since Lollipop, ActionBar is now deprecated. A new component called &lt;strong&gt;Toolbar&lt;/strong&gt; was introduced instead which is easier to use and more versatile. This can be used as any other normal view in your activity layout.&lt;/p&gt;
&lt;p&gt;Create &lt;em&gt;toolbar.xml&lt;/em&gt; in your &lt;em&gt;res/layout&lt;/em&gt; folder. Apart from the compulsory width and height. You need the theme and minimum height (line 7 &amp;amp; 9) defined at the least.&lt;/p&gt;
&lt;p&gt;The toolbar MUST use the primary color as per Material Design guidelines. It can be referenced via &lt;em&gt;?attr/colorPrimary&lt;/em&gt; as well. Default toolbar height is set using &lt;em&gt;?attr/actionBarSize&lt;/em&gt;. I&apos;ve used a dark Toolbar theme so that my text by default is white against my background. Since a dark theme is set, the popup will be dark as well. To keep overflow menu light, hence I&apos;ve set a light theme for it.&lt;/p&gt;
&lt;p&gt;Now before we use our Toolbar, we need to tell our themes to NOT display a default ActionBar first. Add the following line to &lt;em&gt;styles.xml&lt;/em&gt; in both your &lt;em&gt;values&lt;/em&gt; and &lt;em&gt;values-v21&lt;/em&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; true
 false
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While we’re at it, why not allow Lollipop to make use of its beautiful activity transitions? Add these lines to your &lt;em&gt;styles.xml&lt;/em&gt; under &lt;em&gt;values-v21.&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;true
true
true
@android:transition/move
@android:transition/move
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;strong&gt;Adding the toolbar&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Since toolbar is a view, we need to add it to our activity layout. Open &lt;em&gt;res/layout/activity_main/xml&lt;/em&gt;. Firstly, remove the default padding in RelativeLayout, and add this line below:&lt;/p&gt;
&lt;p&gt;As per convention, the Toolbar must be defined in a separate XML file (&lt;em&gt;toolbar.xml)&lt;/em&gt; and then must be included in our layout by using the  tag.&lt;/p&gt;
&lt;p&gt;Now, earlier after including the &lt;em&gt;Toolbar&lt;/em&gt;, any layout I added below it, would automatically have some padding. That is after setting the &lt;em&gt;Toolbar&lt;/em&gt; as an &lt;em&gt;ActionBar,&lt;/em&gt; the views below wouldn&apos;t overlap the toolbar. Oddly, after the new &lt;em&gt;AppCompat-v22&lt;/em&gt; update, I find the layout overlapping.&lt;/p&gt;
&lt;p&gt;Now for those of you who find your layout overlapping the Toolbar, its a relatively simple fix. Just add a &lt;code&gt;android:layout_marginTop=&quot;?attr/actionBarSize&quot;&lt;/code&gt; to your layout. Like for instance how I&apos;ve added it to my RelativeLayout below the Toolbar.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
    

    

        //Your main layout here

    

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;strong&gt;Toolbar as ActionBar&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Lastly, we need to tell Android to use our specified toolbar to behave like an ActionBar. Once this step is done, we can interact with it like we used to with the ActionBar. Enough XML for now, let’s dive into Java. Open your &lt;em&gt;java/packagename/MainActivity.java&lt;/em&gt; and reference the toolbar.&lt;/p&gt;
&lt;p&gt;Create a toolbar variable and initialize like you normally would for any view.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class MainActivity extends AppCompatActivity{
    Toolbar toolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
    ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;UPDATE: You must now extend &lt;em&gt;AppCompatActivity&lt;/em&gt; as &lt;em&gt;ActionBarActivity&lt;/em&gt; is deprecated.&lt;/p&gt;
&lt;p&gt;The key is line 10 where it instructs the activity to use our Toolbar as its ActionBar. After this, the Toolbar can be referenced as a regular ActionBar using &lt;em&gt;getSupportActionBar()&lt;/em&gt; to perform your actions.&lt;/p&gt;
&lt;p&gt;That took longer than expected! Time for some action. Hit &lt;strong&gt;Shift+F10&lt;/strong&gt; to compile your app and run. Your app should be looking like this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-material-design-tutorial/Screenshot_2015-04-05-11-56-49-e1428735686215-193x300.png&quot; alt=&quot;android material design app on pre lollipop device&quot; title=&quot;As seen on Jelly Bean 4.2.2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now you may notice, why is there no shadow under my toolbar? That because we need to add it. It won&apos;t be included by default.&lt;/p&gt;
&lt;h3&gt;Toolbar Shadow&lt;/h3&gt;
&lt;p&gt;Now there are two ways of doing this.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Use a 9-patch for the shadow&lt;/li&gt;
&lt;li&gt;Create one using XML&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now I&apos;m going to keep this clean and use an XML generated shadow for my Toolbar. After that, we can reference this shadow as a view in our layout.&lt;/p&gt;
&lt;p&gt;Create &lt;em&gt;shadow.xml&lt;/em&gt; under &lt;em&gt;res/drawable/&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The XML is simply a gradient that goes from from a 64% of black (#000000) to a transparent color (The first 2 values after the # is the hexadecimal value for opacity). The angle specifies the direction of the gradient. We need it vertical, hence 90.&lt;/p&gt;
&lt;p&gt;For a more detailed how-to  on Toolbar elevation (shadow) , I suggest you read &lt;a href=&quot;https://blog.iamsuleiman.com/add-a-toolbar-elevation-on-pre-lollipop/&quot;&gt;this&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Head back to your &lt;em&gt;activity_main.xml.&lt;/em&gt; We now need to include the shadow we just created as a view directly BELOW our toolbar.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-material-design-tutorial/Screenshot_2015-04-12-12-07-22-e1428823542127-194x300.png&quot; alt=&quot;toolbar with elevation on pre lollipop&quot; title=&quot;Toolbar with shadow drawable&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./android-material-design-tutorial/11066123_10205982672706715_1870257390_o-e1428824619252-182x300.jpg&quot; alt=&quot;Toolbar with shadow drawable on Nexus 5 Lollipop&quot; title=&quot;Toolbar with shadow drawable on Nexus 5 Lollipop&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now some of you may ask &quot;&lt;em&gt;Why not use the toolbar elevation property?&lt;/em&gt;&quot;. That property applies only on Lollipop devices. For pre-Lollipop, we&apos;re on our own. Honestly, there&apos;s not much of a difference between the two shadows as you can see above, but if you really want to use that elevation instead of the shadow drawable on Lollipop at least, then you could do this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Check if the Android SDK version is Lollipop&lt;/p&gt;
&lt;p&gt;&lt;code&gt;if (Build.VERSION.SDK_INT &amp;gt;= Build.VERSION_CODES.LOLLIPOP)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If it is, then remove the shadow View with &lt;code&gt;view.setVisibility(View.GONE);&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Elevate the toolbar using  &lt;code&gt;getSupportActionBar().setElevation(4);&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;p&gt;IMAGE CREDIT: &lt;a href=&quot;http://www.google.com/design/spec/material-design/introduction.html&quot;&gt;Google Material Design&lt;/a&gt; You can download the sample project &lt;a href=&quot;https://drive.google.com/uc?export=download&amp;amp;id=0BwdlpxsQ4WDCTjI1RGFuQkt4MEk&quot;&gt;here&lt;/a&gt; or head over to &lt;a href=&quot;https://github.com/Suleiman19/Android-Material-Design-for-pre-Lollipop&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item></channel></rss>