From d83ded01933d653ac7ea62e9f5f9c4915263a5ca Mon Sep 17 00:00:00 2001 From: Alex Ning Date: Fri, 24 Aug 2018 10:38:37 +0800 Subject: [PATCH] Display a thumbtack icon if the post is stickied on top. Display a gold icon and the number of gold if the post is gilded. Load subreddit icons in LoadSubredditIconAsyncTaskListener instead of loading the icons in onPostExecute() of LoadSubredditIconAsyncTask in order to avoid loading icons on a destroyed activity when start the Activity and then press back or up button immediately. --- .../LoadSubredditIconAsyncTask.java | 28 ++---- .../infinityforreddit/ParsePost.java | 48 +++++++--- .../infinityforreddit/PostData.java | 34 ++++++- .../infinityforreddit/PostFragment.java | 4 - .../PostRecyclerViewAdapter.java | 89 +++++++++++++----- .../ViewPostDetailActivity.java | 51 +++++++++- app/src/main/res/drawable/gold.png | Bin 0 -> 18745 bytes app/src/main/res/drawable/thumbtack.png | Bin 0 -> 6774 bytes .../res/layout/activity_view_post_detail.xml | 21 +++++ app/src/main/res/layout/item_post.xml | 46 +++++++-- app/src/main/res/values/colors.xml | 2 + app/src/main/res/values/strings.xml | 89 +----------------- 12 files changed, 246 insertions(+), 166 deletions(-) create mode 100644 app/src/main/res/drawable/gold.png create mode 100644 app/src/main/res/drawable/thumbtack.png diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/LoadSubredditIconAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/LoadSubredditIconAsyncTask.java index 928951fc..97795c54 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/LoadSubredditIconAsyncTask.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/LoadSubredditIconAsyncTask.java @@ -1,31 +1,22 @@ package ml.docilealligator.infinityforreddit; -import android.content.Context; import android.os.AsyncTask; -import com.bumptech.glide.Glide; - -import java.lang.ref.WeakReference; - -import de.hdodenhof.circleimageview.CircleImageView; - class LoadSubredditIconAsyncTask extends AsyncTask { - private final WeakReference contextWeakReference; - private final WeakReference circleImageViewWeakReference; + interface LoadSubredditIconAsyncTaskListener { + void loadIconSuccess(String iconImageUrl); + } private SubredditDao subredditDao; private String subredditName; private String iconImageUrl; - private PostData postData; + private LoadSubredditIconAsyncTaskListener loadSubredditIconAsyncTaskListener; - LoadSubredditIconAsyncTask(Context context, CircleImageView iconImageView, - SubredditDao subredditDao, String subredditName, - PostData postData) { - contextWeakReference = new WeakReference<>(context); - circleImageViewWeakReference = new WeakReference<>(iconImageView); + LoadSubredditIconAsyncTask(SubredditDao subredditDao, String subredditName, + LoadSubredditIconAsyncTaskListener loadSubredditIconAsyncTaskListener) { this.subredditDao = subredditDao; this.subredditName = subredditName; - this.postData = postData; + this.loadSubredditIconAsyncTaskListener = loadSubredditIconAsyncTaskListener; } @Override @@ -41,7 +32,8 @@ class LoadSubredditIconAsyncTask extends AsyncTask { @Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); - Context context = contextWeakReference.get(); + loadSubredditIconAsyncTaskListener.loadIconSuccess(iconImageUrl); + /*Context context = contextWeakReference.get(); CircleImageView circleImageView = circleImageViewWeakReference.get(); if(context != null && circleImageView != null) { @@ -52,6 +44,6 @@ class LoadSubredditIconAsyncTask extends AsyncTask { } } - postData.setSubredditIconUrl(iconImageUrl); + postData.setSubredditIconUrl(iconImageUrl);*/ } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java index caebd825..ffc2be9b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java @@ -70,7 +70,9 @@ class ParsePost { String title = data.getString(JSONUtils.TITLE_KEY); int score = data.getInt(JSONUtils.SCORE_KEY); int voteType; + int gilded = data.getInt(JSONUtils.GILDED_KEY); boolean nsfw = data.getBoolean(JSONUtils.NSFW_KEY); + boolean stickied = data.getBoolean(JSONUtils.STICKIED_KEY); if(data.isNull(JSONUtils.LIKES_KEY)) { voteType = 0; @@ -93,10 +95,10 @@ class ParsePost { //Cross post data = data.getJSONArray(JSONUtils.CROSSPOST_PARENT_LIST).getJSONObject(0); parseData(data, permalink, newPostData, id, fullName, subredditName, - formattedPostTime, title, previewUrl, score, voteType, nsfw, i); + formattedPostTime, title, previewUrl, score, voteType, gilded, nsfw, stickied, i); } else { parseData(data, permalink, newPostData, id, fullName, subredditName, - formattedPostTime, title, previewUrl, score, voteType, nsfw, i); + formattedPostTime, title, previewUrl, score, voteType, gilded, nsfw, stickied, i); } } } catch (JSONException e) { @@ -119,8 +121,9 @@ class ParsePost { } private void parseData(JSONObject data, String permalink, ArrayList bestPostData, - String id, String fullName, String subredditName, String formattedPostTime, String title, - String previewUrl, int score, int voteType, boolean nsfw, int i) throws JSONException { + String id, String fullName, String subredditName, String formattedPostTime, + String title, String previewUrl, int score, int voteType, int gilded, + boolean nsfw, boolean stickied, int i) throws JSONException { boolean isVideo = data.getBoolean(JSONUtils.IS_VIDEO_KEY); String url = data.getString(JSONUtils.URL_KEY); @@ -129,7 +132,8 @@ class ParsePost { //Text post Log.i("text", Integer.toString(i)); int postType = PostData.TEXT_TYPE; - PostData postData = new PostData(id, fullName, subredditName, formattedPostTime, title, permalink, score, postType, voteType, nsfw); + PostData postData = new PostData(id, fullName, subredditName, formattedPostTime, + title, permalink, score, postType, voteType, gilded, nsfw, stickied); if(data.isNull(JSONUtils.SELFTEXT_HTML_KEY)) { postData.setSelfText(""); } else { @@ -140,7 +144,13 @@ class ParsePost { //No preview link post Log.i("no preview link", Integer.toString(i)); int postType = PostData.NO_PREVIEW_LINK_TYPE; - PostData linkPostData = new PostData(id, fullName, subredditName, formattedPostTime, title, previewUrl, url, permalink, score, postType, voteType, nsfw); + PostData linkPostData = new PostData(id, fullName, subredditName, formattedPostTime, + title, previewUrl, url, permalink, score, postType, voteType, gilded, nsfw, stickied); + if(data.isNull(JSONUtils.SELFTEXT_HTML_KEY)) { + linkPostData.setSelfText(""); + } else { + linkPostData.setSelfText(data.getString(JSONUtils.SELFTEXT_HTML_KEY).trim()); + } bestPostData.add(linkPostData); } } else if(isVideo) { @@ -150,7 +160,8 @@ class ParsePost { int postType = PostData.VIDEO_TYPE; String videoUrl = redditVideoObject.getString(JSONUtils.DASH_URL_KEY); - PostData videoPostData = new PostData(id, fullName, subredditName, formattedPostTime, title, previewUrl, permalink, score, postType, voteType, nsfw, true); + PostData videoPostData = new PostData(id, fullName, subredditName, formattedPostTime, + title, previewUrl, permalink, score, postType, voteType, gilded, nsfw, stickied, true); videoPostData.setVideoUrl(videoUrl); videoPostData.setDownloadableGifOrVideo(false); @@ -164,7 +175,8 @@ class ParsePost { int postType = PostData.GIF_VIDEO_TYPE; String videoUrl = variations.getJSONObject(JSONUtils.VARIANTS_KEY).getJSONObject(JSONUtils.MP4_KEY).getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY); String gifDownloadUrl = variations.getJSONObject(JSONUtils.VARIANTS_KEY).getJSONObject(JSONUtils.GIF_KEY).getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY); - PostData post = new PostData(id, fullName, subredditName, formattedPostTime, title, previewUrl, permalink, score, postType, voteType, nsfw, false); + PostData post = new PostData(id, fullName, subredditName, formattedPostTime, title, + previewUrl, permalink, score, postType, voteType, gilded, nsfw, stickied, false); post.setVideoUrl(videoUrl); post.setDownloadableGifOrVideo(true); @@ -178,7 +190,8 @@ class ParsePost { String videoUrl = data.getJSONObject(JSONUtils.PREVIEW_KEY) .getJSONObject(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY).getString(JSONUtils.DASH_URL_KEY); - PostData post = new PostData(id, fullName, subredditName, formattedPostTime, title, previewUrl, permalink, score, postType, voteType, nsfw, true); + PostData post = new PostData(id, fullName, subredditName, formattedPostTime, title, + previewUrl, permalink, score, postType, voteType, gilded, nsfw, stickied, true); post.setVideoUrl(videoUrl); post.setDownloadableGifOrVideo(false); @@ -189,12 +202,19 @@ class ParsePost { //Image post Log.i("image", Integer.toString(i)); int postType = PostData.IMAGE_TYPE; - bestPostData.add(new PostData(id, fullName, subredditName, formattedPostTime, title, url, url, permalink, score, postType, voteType, nsfw)); + bestPostData.add(new PostData(id, fullName, subredditName, formattedPostTime, + title, url, url, permalink, score, postType, voteType, gilded, nsfw, stickied)); } else { //Link post Log.i("link", Integer.toString(i)); int postType = PostData.LINK_TYPE; - PostData linkPostData = new PostData(id, fullName, subredditName, formattedPostTime, title, previewUrl, url, permalink, score, postType, voteType, nsfw); + PostData linkPostData = new PostData(id, fullName, subredditName, formattedPostTime, + title, previewUrl, url, permalink, score, postType, voteType, gilded, nsfw, stickied); + if(data.isNull(JSONUtils.SELFTEXT_HTML_KEY)) { + linkPostData.setSelfText(""); + } else { + linkPostData.setSelfText(data.getString(JSONUtils.SELFTEXT_HTML_KEY).trim()); + } bestPostData.add(linkPostData); } } @@ -203,12 +223,14 @@ class ParsePost { //Image post Log.i("CP no preview image", Integer.toString(i)); int postType = PostData.IMAGE_TYPE; - bestPostData.add(new PostData(id, fullName, subredditName, formattedPostTime, title, url, url, permalink, score, postType, voteType, nsfw)); + bestPostData.add(new PostData(id, fullName, subredditName, formattedPostTime, title, + url, url, permalink, score, postType, voteType, gilded, nsfw, stickied)); } else { //Link post Log.i("CP no preview link", Integer.toString(i)); int postType = PostData.LINK_TYPE; - PostData linkPostData = new PostData(id, fullName, subredditName, formattedPostTime, title, previewUrl, url, permalink, score, postType, voteType, nsfw); + PostData linkPostData = new PostData(id, fullName, subredditName, formattedPostTime, + title, previewUrl, url, permalink, score, postType, voteType, gilded, nsfw, stickied); bestPostData.add(linkPostData); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostData.java index c91cc333..0626088f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostData.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostData.java @@ -30,11 +30,15 @@ class PostData implements Parcelable { private int score; private int postType; private int voteType; + private int gilded; private boolean nsfw; + private boolean stickied; private boolean isDashVideo; private boolean isDownloadableGifOrVideo; - PostData(String id, String fullName, String subredditName, String postTime, String title, String previewUrl, String permalink, int score, int postType, int voteType, boolean nsfw, boolean isDashVideo) { + PostData(String id, String fullName, String subredditName, String postTime, String title, + String previewUrl, String permalink, int score, int postType, int voteType, int gilded, + boolean nsfw, boolean stickied, boolean isDashVideo) { this.id = id; this.fullName = fullName; this.subredditName = subredditName; @@ -45,11 +49,15 @@ class PostData implements Parcelable { this.score = score; this.postType = postType; this.voteType = voteType; + this.gilded = gilded; this.nsfw = nsfw; + this.stickied = stickied; this.isDashVideo = isDashVideo; } - PostData(String id, String fullName, String subredditName, String postTime, String title, String previewUrl, String url, String permalink, int score, int postType, int voteType, boolean nsfw) { + PostData(String id, String fullName, String subredditName, String postTime, String title, + String previewUrl, String url, String permalink, int score, int postType, int voteType, + int gilded, boolean nsfw, boolean stickied) { this.id = id; this.fullName = fullName; this.subredditName = subredditName; @@ -61,10 +69,14 @@ class PostData implements Parcelable { this.score = score; this.postType = postType; this.voteType = voteType; + this.gilded = gilded; this.nsfw = nsfw; + this.stickied = stickied; } - PostData(String id, String fullName, String subredditName, String postTime, String title, String permalink, int score, int postType, int voteType, boolean nsfw) { + PostData(String id, String fullName, String subredditName, String postTime, String title, + String permalink, int score, int postType, int voteType, int gilded, boolean nsfw, + boolean stickied) { this.id = id; this.fullName = fullName; this.subredditName = subredditName; @@ -74,7 +86,9 @@ class PostData implements Parcelable { this.score = score; this.postType = postType; this.voteType = voteType; + this.gilded = gilded; this.nsfw = nsfw; + this.stickied = stickied; } protected PostData(Parcel in) { @@ -93,7 +107,9 @@ class PostData implements Parcelable { score = in.readInt(); postType = in.readInt(); voteType = in.readInt(); + gilded = in.readInt(); nsfw = in.readByte() != 0; + stickied = in.readByte() != 0; isDashVideo = in.readByte() != 0; isDownloadableGifOrVideo = in.readByte() != 0; } @@ -198,7 +214,11 @@ class PostData implements Parcelable { return voteType; } - public boolean getNSFW() { + public int getGilded() { + return gilded; + } + + public boolean isNSFW() { return nsfw; } @@ -219,6 +239,10 @@ class PostData implements Parcelable { return isDownloadableGifOrVideo; } + public boolean isStickied() { + return stickied; + } + @Override public void writeToParcel(Parcel parcel, int i) { parcel.writeString(id); @@ -236,7 +260,9 @@ class PostData implements Parcelable { parcel.writeInt(score); parcel.writeInt(postType); parcel.writeInt(voteType); + parcel.writeInt(gilded); parcel.writeByte((byte) (nsfw ? 1 : 0)); + parcel.writeByte((byte) (stickied ? 1 : 0)); parcel.writeByte((byte) (isDashVideo ? 1 : 0)); parcel.writeByte((byte) (isDownloadableGifOrVideo ? 1 : 0)); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java index 49220d94..e8b10896 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostFragment.java @@ -188,10 +188,6 @@ public class PostFragment extends Fragment { mProgressBar.setVisibility(View.VISIBLE); - /*Uri uri = Uri.parse(RedditUtils.OAUTH_API_BASE_URI + RedditUtils.BEST_POST_SUFFIX) - .buildUpon().appendQueryParameter(RedditUtils.RAW_JSON_KEY, RedditUtils.RAW_JSON_VALUE) - .build();*/ - StringRequest postRequest = new StringRequest(Request.Method.GET, mQueryPostUrl, new Response.Listener() { @Override public void onResponse(String response) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java index 933af11d..724fb753 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PostRecyclerViewAdapter.java @@ -86,22 +86,36 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter 0) { + ((DataViewHolder) holder).gildedImageView.setVisibility(View.VISIBLE); + glide.load(R.drawable.gold).into(((DataViewHolder) holder).gildedImageView); + ((DataViewHolder) holder).gildedNumberTextView.setVisibility(View.VISIBLE); + String gildedNumber = mContext.getResources().getString(R.string.gilded, gilded); + ((DataViewHolder) holder).gildedNumberTextView.setText(gildedNumber); + } + if(nsfw) { ((DataViewHolder) holder).nsfwTextView.setVisibility(View.VISIBLE); } @@ -147,6 +169,11 @@ class PostRecyclerViewAdapter extends RecyclerView.Adapter 0) { + gildedImageView.setVisibility(View.VISIBLE); + Glide.with(this).load(R.drawable.gold).into(gildedImageView); + gildedNumberTextView.setVisibility(View.VISIBLE); + String gildedNumber = getResources().getString(R.string.gilded, mPostData.getGilded()); + gildedNumberTextView.setText(gildedNumber); + } + + if(mPostData.isNSFW()) { nsfwTextView.setVisibility(View.VISIBLE); } scoreTextView.setText(Integer.toString(mPostData.getScore())); @@ -177,6 +204,10 @@ public class ViewPostDetailActivity extends AppCompatActivity { case PostData.LINK_TYPE: relativeLayout.setVisibility(View.VISIBLE); typeTextView.setText("LINK"); + if(!mPostData.getSelfText().equals("")) { + contentTextView.setVisibility(View.VISIBLE); + contentTextView.setHtml(mPostData.getSelfText()); + } String linkPreviewUrl = mPostData.getPreviewUrl(); Glide.with(this).load(linkPreviewUrl).listener(new RequestListener() { @Override @@ -279,6 +310,10 @@ public class ViewPostDetailActivity extends AppCompatActivity { break; case PostData.NO_PREVIEW_LINK_TYPE: typeTextView.setText("LINK"); + if(!mPostData.getSelfText().equals("")) { + contentTextView.setVisibility(View.VISIBLE); + contentTextView.setHtml(mPostData.getSelfText()); + } noPreviewLinkImageView.setVisibility(View.VISIBLE); noPreviewLinkImageView.setOnClickListener(new View.OnClickListener() { @Override @@ -535,4 +570,12 @@ public class ViewPostDetailActivity extends AppCompatActivity { finish(); } } + + @Override + protected void onDestroy() { + super.onDestroy(); + if(mLoadSubredditIconAsyncTask != null) { + mLoadSubredditIconAsyncTask.cancel(true); + } + } } diff --git a/app/src/main/res/drawable/gold.png b/app/src/main/res/drawable/gold.png new file mode 100644 index 0000000000000000000000000000000000000000..df04fbe8c37e720ebd42b07d2c617ee9b828ed9a GIT binary patch literal 18745 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 D(Qw51 literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/activity_view_post_detail.xml b/app/src/main/res/layout/activity_view_post_detail.xml index d3b0b3ce..64a648c2 100644 --- a/app/src/main/res/layout/activity_view_post_detail.xml +++ b/app/src/main/res/layout/activity_view_post_detail.xml @@ -103,6 +103,27 @@ android:background="@drawable/rounded_corner" android:textColor="@android:color/white" /> + + + + + + + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp"> + + + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index bb250be8..ed9b8e8a 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -7,4 +7,6 @@ #E91E63 #88000000 + + #FFC107 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c7505627..2014e3bb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -22,93 +22,6 @@ Subscriptions Subscribers: %1$d Online: %1$d - - "Material is the metaphor.\n\n" - "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.\n" - "Surfaces and edges of the material provide visual cues that are grounded in reality. The " - "use of familiar tactile attributes helps users quickly understand affordances. Yet the " - "flexibility of the material creates new affordances that supercede those in the physical " - "world, without breaking the rules of physics.\n" - "The fundamentals of light, surface, and movement are key to conveying how objects move, " - "interact, and exist in space and in relation to each other. Realistic lighting shows " - "seams, divides space, and indicates moving parts.\n\n" - - "Bold, graphic, intentional.\n\n" - - "The foundational elements of print based design typography, grids, space, scale, color, " - "and use of imagery guide visual treatments. These elements do far more than please the " - "eye. They create hierarchy, meaning, and focus. Deliberate color choices, edge to edge " - "imagery, large scale typography, and intentional white space create a bold and graphic " - "interface that immerse the user in the experience.\n" - "An emphasis on user actions makes core functionality immediately apparent and provides " - "waypoints for the user.\n\n" - - "Motion provides meaning.\n\n" - - "Motion respects and reinforces the user as the prime mover. Primary user actions are " - "inflection points that initiate motion, transforming the whole design.\n" - "All action takes place in a single environment. Objects are presented to the user without " - "breaking the continuity of experience even as they transform and reorganize.\n" - "Motion is meaningful and appropriate, serving to focus attention and maintain continuity. " - "Feedback is subtle yet clear. Transitions are efficient yet coherent.\n\n" - - "3D world.\n\n" - - "The material environment is a 3D space, which means all objects have x, y, and z " - "dimensions. The z-axis is perpendicularly aligned to the plane of the display, with the " - "positive z-axis extending towards the viewer. Every sheet of material occupies a single " - "position along the z-axis and has a standard 1dp thickness.\n" - "On the web, the z-axis is used for layering and not for perspective. The 3D world is " - "emulated by manipulating the y-axis.\n\n" - - "Light and shadow.\n\n" - - "Within the material environment, virtual lights illuminate the scene. Key lights create " - "directional shadows, while ambient light creates soft shadows from all angles.\n" - "Shadows in the material environment are cast by these two light sources. In Android " - "development, shadows occur when light sources are blocked by sheets of material at " - "various positions along the z-axis. On the web, shadows are depicted by manipulating the " - "y-axis only. The following example shows the card with a height of 6dp.\n\n" - - "Resting elevation.\n\n" - - "All material objects, regardless of size, have a resting elevation, or default elevation " - "that does not change. If an object changes elevation, it should return to its resting " - "elevation as soon as possible.\n\n" - - "Component elevations.\n\n" - - "The resting elevation for a component type is consistent across apps (e.g., FAB elevation " - "does not vary from 6dp in one app to 16dp in another app).\n" - "Components may have different resting elevations across platforms, depending on the depth " - "of the environment (e.g., TV has a greater depth than mobile or desktop).\n\n" - - "Responsive elevation and dynamic elevation offsets.\n\n" - - "Some component types have responsive elevation, meaning they change elevation in response " - "to user input (e.g., normal, focused, and pressed) or system events. These elevation " - "changes are consistently implemented using dynamic elevation offsets.\n" - "Dynamic elevation offsets are the goal elevation that a component moves towards, relative " - "to the component’s resting state. They ensure that elevation changes are consistent " - "across actions and component types. For example, all components that lift on press have " - "the same elevation change relative to their resting elevation.\n" - "Once the input event is completed or cancelled, the component will return to its resting " - "elevation.\n\n" - - "Avoiding elevation interference.\n\n" - - "Components with responsive elevations may encounter other components as they move between " - "their resting elevations and dynamic elevation offsets. Because material cannot pass " - "through other material, components avoid interfering with one another any number of ways, " - "whether on a per component basis or using the entire app layout.\n" - "On a component level, components can move or be removed before they cause interference. " - "For example, a floating action button (FAB) can disappear or move off screen before a " - "user picks up a card, or it can move if a snackbar appears.\n" - "On the layout level, design your app layout to minimize opportunities for interference. " - "For example, position the FAB to one side of stream of a cards so the FAB won’t interfere " - "when a user tries to pick up one of cards.\n\n" - + x%1$d