Add Loading Default Image and Remove Progress Bar

This commit is contained in:
Aargonian
2016-02-15 05:47:23 -05:00
parent 444eefe3c4
commit ca95fccc6b
20 changed files with 376 additions and 196 deletions

View File

@@ -36,4 +36,5 @@ dependencies {
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.jakewharton:butterknife:7.0.1'
compile 'com.github.justzak:dilatingdotsprogressbar:1.0.1'
compile 'com.android.support:recyclerview-v7:23.1.1'
}

View File

@@ -78,7 +78,7 @@ public class DetailFragment extends Fragment
movie = new Movie(
"Pick a Movie!",
"You can browse movies in the list and touch one to see its details here!",
BitmapFactory.decodeResource(this.getResources(), R.mipmap.noimage),
BitmapFactory.decodeResource(this.getResources(), R.drawable.noimage),
"",
0,
10.0,

View File

@@ -3,7 +3,7 @@ package com.example.android.popularmovies;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -18,13 +18,13 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.zl.reik.dilatingdotsprogressbar.DilatingDotsProgressBar;
import com.nytegear.android.network.NetworkUtil;
import com.nytegear.android.view.AsyncImage;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
@@ -49,7 +49,6 @@ public class DiscoverFragment extends Fragment implements MovieAdapter.MovieItem
private int currentPage;
@Bind(R.id.movieContainer) FrameLayout movieContainer;
@Bind(R.id.progress) DilatingDotsProgressBar dotProgress;
public DiscoverFragment() {}
@@ -122,7 +121,6 @@ public class DiscoverFragment extends Fragment implements MovieAdapter.MovieItem
mMoviesGridView.setLayoutManager(mManager);
mMoviesGridView.setAdapter(mAdapter);
movieContainer.addView(mMoviesGridView);
dotProgress.hideNow();
addMovies();
if(savedInstanceState != null)
mMoviesGridView.setVerticalScrollbarPosition(savedInstanceState.getInt("SCROLL_POS"));
@@ -152,14 +150,11 @@ public class DiscoverFragment extends Fragment implements MovieAdapter.MovieItem
public void addMovies() {
if(currentPage < 11)
{
dotProgress.showNow();
loadingMovies = true;
DiscoverTask task = new DiscoverTask() {
@Override
public void onPostExecute(Void result) {
loadingMovies = false;
dotProgress.hideNow();
dotProgress.reset();
}
};
task.execute(currentPage++);
@@ -227,23 +222,17 @@ public class DiscoverFragment extends Fragment implements MovieAdapter.MovieItem
else
return null;
JSONArray results = movieList.getJSONArray("results");
//We need to get the posters. First thing, determine the number of processors avail
//We can use that to determine an upper limit to parallel threads.
int currentThreadCount = 0;
int processors = Runtime.getRuntime().availableProcessors();
for(int i = 0; i < results.length(); i++)
{
Integer id = results.getJSONObject(i).getInt("id");
String title = results.getJSONObject(i).getString("original_title");
Bitmap poster = null;
try {
poster = Movie.getPoster(context,
results.getJSONObject(i).getString("poster_path"));
} catch (IOException ex) {
Log.e(LOG_TAG, "Unable to retrieve poster! " + ex.getMessage(), ex);
}
publishProgress(new MovieAdapter.MovieReference(id, poster, title));
String posterURL = Movie.TMDB_POSTER_URL+
results.getJSONObject(i).getString("poster_path");
AsyncImage image = new AsyncImage(context,
BitmapFactory.decodeResource(context.getResources(),
R.drawable.loading));
image.setImageURL(posterURL);
publishProgress(new MovieAdapter.MovieReference(id, title, image));
}
} catch (MalformedURLException ex) {
Log.e(LOG_TAG, "Malformed URL: " + ex.getMessage(), ex);

View File

@@ -7,6 +7,8 @@ import android.support.annotation.NonNull;
import android.util.Log;
import android.widget.ImageView;
import com.nytegear.android.network.NetworkUtil;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -74,8 +76,10 @@ public class Movie implements Comparable<Movie>
//TODO: Implementation tied explicitly to Picasso. Check out other libraries!
public static Bitmap getPoster(Context context, String posterPath) throws IOException
{
if(context == null || posterPath == null || posterPath.isEmpty())
return null;
return NetworkUtil.getImage(TMDB_POSTER_URL + posterPath, context,
BitmapFactory.decodeResource(context.getResources(), R.mipmap.noimage));
BitmapFactory.decodeResource(context.getResources(), R.drawable.loading));
}
private String title;

View File

@@ -2,12 +2,17 @@ package com.example.android.popularmovies;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import com.nytegear.android.view.AsyncImage;
import com.nytegear.android.view.WebImageView;
import java.util.ArrayList;
/**
@@ -18,10 +23,10 @@ public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.ViewHolder>
//Struct-like class for inner use
public static class MovieReference {
public final Integer id;
public final Bitmap poster;
public final String title;
public final AsyncImage poster;
public MovieReference(Integer id, Bitmap poster, String title) {
public MovieReference(Integer id, String title, AsyncImage poster) {
this.id = id;
this.poster = poster;
this.title = title;
@@ -42,7 +47,8 @@ public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.ViewHolder>
}
public class ViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener {
implements View.OnClickListener, AsyncImage.AsyncImageListener {
private String LOG_TAG = ViewHolder.class.getName();
public ImageView imageView;
public ViewHolder(ImageView v)
{
@@ -51,6 +57,20 @@ public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.ViewHolder>
imageView.setOnClickListener(this);
}
@Override
public void imageDownloaded(Bitmap bm)
{
Log.e(LOG_TAG, "IMAGE DOWNLOADED WOOT");
imageView.setImageBitmap(bm);
}
@Override
public void downloadFailed()
{
imageView.setImageBitmap(
BitmapFactory.decodeResource(context.getResources(), R.drawable.noimage));
}
@Override
public void onClick(View v) {
if(listener != null) {
@@ -68,9 +88,9 @@ public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.ViewHolder>
@Override
public MovieAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
ImageView view = new ImageView(parent.getContext());
WebImageView view = new WebImageView(parent.getContext());
view.setAdjustViewBounds(true);
view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
view.setScaleType(ImageView.ScaleType.FIT_XY);
return new ViewHolder(view);
}
@@ -80,7 +100,8 @@ public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.ViewHolder>
{
MovieReference movie = dataset.get(position);
if(movie != null) {
holder.imageView.setImageBitmap(movie.poster);
movie.poster.setAsyncImageListener(holder);
holder.imageView.setImageBitmap(movie.poster.getImage());
}
}

View File

@@ -1,8 +1,7 @@
package com.example.android.popularmovies;
package com.nytegear.android.network;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import com.squareup.picasso.Downloader;
@@ -16,6 +15,10 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
/**
* Created by Aaron Helton on 1/30/2016
*/
@@ -27,7 +30,7 @@ public final class NetworkUtil
public static String getURL(String urlString) {
long nano = System.nanoTime();
String res = getUrlImpl(urlString);
String res = getUrlImpl2(urlString);
//Statistics
long time = (System.nanoTime()-nano)/1000000;
@@ -54,7 +57,7 @@ public final class NetworkUtil
//Tests on target device show that the straight HTTPUrlConnection version actually performs
//faster on average than Picasso, and images being stored as an ImageView later means we
//don't quite benefit as much from the image cache to make it worth using.
Bitmap bm = defImageImpl2(url, context, defImg);
Bitmap bm = defImageImpl(url, context, defImg);
long time = (System.nanoTime()-nano)/1000000;
imgRequestTimes.add(time);
@@ -85,21 +88,6 @@ public final class NetworkUtil
}
}
private static Bitmap defImageImpl2(String urlString, Context context, Bitmap defImg)
{
try {
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
return BitmapFactory.decodeStream(connection.getInputStream());
} catch (MalformedURLException ex) {
Log.e(LOG_TAG, "Malformed URL: " + urlString + ";\n" + ex.getMessage(), ex);
return defImg;
} catch (IOException ex) {
Log.e(LOG_TAG, "I/O ERROR: " + ex.getMessage(), ex);
return defImg;
}
}
private static String getUrlImpl(String urlString)
{
if(urlString == null || urlString.isEmpty())
@@ -148,4 +136,20 @@ public final class NetworkUtil
else
return null;
}
private static String getUrlImpl2(String urlString)
{
try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(new URL(urlString))
.build();
Response response = client.newCall(request).execute();
return response.body().string();
} catch (IOException ex) {
Log.e(LOG_TAG, "Error Getting Page: " + ex.getMessage(), ex);
return null;
}
}
}

View File

@@ -0,0 +1,83 @@
package com.nytegear.android.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import com.nytegear.android.network.NetworkUtil;
/**
* Created by Aaron Helton on 2/11/2016
*/
public class AsyncImage
{
private Context context;
private Bitmap placeholder;
private Bitmap image;
private AsyncImageListener listener;
public interface AsyncImageListener {
void imageDownloaded(Bitmap bm);
void downloadFailed();
}
public AsyncImage(Context context)
{
this.context = context;
}
public AsyncImage(Context context, Bitmap placeholder)
{
this.context = context;
this.placeholder = placeholder;
}
public void setAsyncImageListener(AsyncImageListener listener)
{
this.listener = listener;
}
public void setImageURL(String url)
{
PosterFetchTask task = new PosterFetchTask();
task.execute(url);
}
public Bitmap getImage()
{
return image == null ? placeholder : image;
}
public Bitmap getPlaceholder()
{
return placeholder;
}
private class PosterFetchTask extends AsyncTask<String, Void, Bitmap>
{
private final String LOG_TAG = PosterFetchTask.class.getSimpleName();
@Override
public Bitmap doInBackground(String... params)
{
if(params.length < 0 || params[0].isEmpty())
return null;
return NetworkUtil.getImage(params[0], context, placeholder);
}
@Override
public void onPostExecute(Bitmap result)
{
image = result;
if(image != null && image != placeholder) {
if(listener != null) {
listener.imageDownloaded(result);
}
} else {
if(listener != null) {
listener.downloadFailed();
}
}
}
}
}

View File

@@ -0,0 +1,78 @@
package com.nytegear.android.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.widget.ImageView;
import com.squareup.picasso.Picasso;
import java.io.IOException;
/**
* Created by Aaron Helton on 2/11/2016
*/
public class WebImageView extends ImageView
{
private Context context;
private Bitmap placeholder;
private Bitmap image;
public WebImageView(Context context)
{
super(context);
this.context = context;
this.placeholder = null;
this.image = null;
}
public WebImageView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
this.context = context;
this.placeholder = null;
this.image = null;
}
public void setPlaceholderImage(Bitmap bitmap)
{
placeholder = bitmap;
if(image == null) {
this.setImageBitmap(placeholder);
}
}
public void setImageUrl(String urlString)
{
PosterFetchTask task = new PosterFetchTask();
task.execute(urlString);
}
private class PosterFetchTask extends AsyncTask<String, Void, Bitmap>
{
private final String LOG_TAG = PosterFetchTask.class.getSimpleName();
@Override
public Bitmap doInBackground(String... params)
{
if(params.length < 0 || params[0].isEmpty())
return null;
try {
return Picasso.with(context).load(params[0]).get();
} catch (IOException ex) {
return placeholder;
}
//return NetworkUtil.getImage(params[0], context, placeholder);
}
@Override
public void onPostExecute(Bitmap result)
{
image = result;
if(image != null) {
setImageBitmap(image);
}
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 853 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 853 B

View File

@@ -25,67 +25,77 @@
android:layout_height="match_parent"
android:background="@color/white"
android:clipToPadding="false">
<RelativeLayout
android:id="@+id/detailRelative"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/releaseDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/releaseHeader"
android:layout_toEndOf="@id/releaseHeader"
android:layout_alignTop="@id/releaseHeader"
/>
<TextView
android:id="@+id/releaseHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/posterImage"
android:layout_toEndOf="@id/posterImage"
android:layout_alignTop="@id/posterImage"
android:textStyle="bold"
android:text="@string/release_header"/>
<TextView
android:id="@+id/ratingHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/releaseHeader"
android:layout_alignStart="@id/releaseHeader"
android:layout_alignLeft="@id/releaseHeader"
android:textStyle="bold"
android:text="@string/rating_header"/>
<TextView
android:id="@+id/rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/ratingHeader"
android:layout_toRightOf="@id/ratingHeader"
android:layout_alignTop="@id/ratingHeader"/>
<ImageView
android:id="@+id/posterImage"
android:adjustViewBounds="true"
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_margin="20dp"
android:scaleType="fitXY"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/overview"
<LinearLayout
android:id="@+id/detailLinear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:id="@id/detailRelative"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_toRightOf="@id/posterImage"
android:layout_toEndOf="@id/posterImage"
android:layout_below="@id/ratingHeader"
android:padding="10dp"
android:elevation="4dp"
android:background="@color/colorPrimary"
android:textColor="@color/white"/>
</RelativeLayout>
android:layout_height="wrap_content">
<TextView
android:id="@+id/releaseDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/releaseHeader"
android:layout_toEndOf="@id/releaseHeader"
android:layout_alignTop="@id/releaseHeader"
/>
<TextView
android:id="@+id/releaseHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/posterImage"
android:layout_toEndOf="@id/posterImage"
android:layout_alignTop="@id/posterImage"
android:textStyle="bold"
android:text="@string/release_header"/>
<TextView
android:id="@+id/ratingHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/releaseHeader"
android:layout_alignStart="@id/releaseHeader"
android:layout_alignLeft="@id/releaseHeader"
android:textStyle="bold"
android:text="@string/rating_header"/>
<TextView
android:id="@+id/rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/ratingHeader"
android:layout_toRightOf="@id/ratingHeader"
android:layout_alignTop="@id/ratingHeader"/>
<ImageView
android:id="@+id/posterImage"
android:adjustViewBounds="true"
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_margin="20dp"
android:scaleType="fitXY"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/overview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_toRightOf="@id/posterImage"
android:layout_toEndOf="@id/posterImage"
android:layout_below="@id/ratingHeader"
android:padding="10dp"
android:elevation="4dp"
android:background="@color/colorPrimary"
android:textColor="@color/white"/>
</RelativeLayout>
<FrameLayout
android:id="@+id/reviewContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</ScrollView>
</RelativeLayout>

View File

@@ -25,80 +25,85 @@
android:layout_height="match_parent"
android:background="@color/white"
android:clipToPadding="false">
<RelativeLayout
android:id="@+id/detailRelative"
android:layout_width="wrap_content"
<LinearLayout
android:id="@+id/detailLinear"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/releaseDate"
android:layout_marginTop="25dp"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
<RelativeLayout
android:id="@+id/detailRelative"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:text="2016-01-29"/>
<TextView
android:id="@+id/releaseHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/releaseDate"
android:layout_toLeftOf="@id/releaseDate"
android:textStyle="bold"
android:text="Release Date: "/>
<TextView
android:id="@+id/ratingHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/releaseHeader"
android:layout_alignStart="@id/releaseHeader"
android:layout_alignLeft="@id/releaseHeader"
android:textStyle="bold"
android:text="Rating: "/>
<TextView
android:id="@+id/rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/ratingHeader"
android:layout_toRightOf="@id/ratingHeader"
android:layout_alignTop="@id/ratingHeader"
android:text="7.7/10"/>
<ImageView
android:id="@+id/posterImage"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_alignParentTop="true"
android:layout_toLeftOf="@id/releaseHeader"
android:layout_toStartOf="@id/releaseHeader"
android:layout_margin="20dp"
android:scaleType="fitXY"
android:src="@mipmap/ic_launcher" />
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1px"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:background="@color/dividerColor"
android:layout_alignLeft="@+id/overview"
android:layout_alignStart="@+id/overview"
android:layout_below="@+id/posterImage"
android:layout_alignRight="@+id/overview"
android:layout_alignEnd="@+id/overview" />
<TextView
android:id="@+id/overview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/divider"
android:layout_margin="10dp"
android:padding="10dp"
android:elevation="4dp"
android:background="@color/colorPrimary"
android:textColor="@color/white"
android:text="In a land long ago and far far away."/>
</RelativeLayout>
android:layout_height="wrap_content">
<TextView
android:id="@+id/releaseDate"
android:layout_marginTop="25dp"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:text="2016-01-29"/>
<TextView
android:id="@+id/releaseHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/releaseDate"
android:layout_toLeftOf="@id/releaseDate"
android:textStyle="bold"
android:text="Release Date: "/>
<TextView
android:id="@+id/ratingHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/releaseHeader"
android:layout_alignStart="@id/releaseHeader"
android:layout_alignLeft="@id/releaseHeader"
android:textStyle="bold"
android:text="Rating: "/>
<TextView
android:id="@+id/rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/ratingHeader"
android:layout_toRightOf="@id/ratingHeader"
android:layout_alignTop="@id/ratingHeader"
android:text="7.7/10"/>
<ImageView
android:id="@+id/posterImage"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_alignParentTop="true"
android:layout_toLeftOf="@id/releaseHeader"
android:layout_toStartOf="@id/releaseHeader"
android:layout_margin="20dp"
android:scaleType="fitXY"
android:src="@mipmap/ic_launcher" />
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1px"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:background="@color/dividerColor"
android:layout_alignLeft="@+id/overview"
android:layout_alignStart="@+id/overview"
android:layout_below="@+id/posterImage"
android:layout_alignRight="@+id/overview"
android:layout_alignEnd="@+id/overview" />
<TextView
android:id="@+id/overview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/divider"
android:layout_margin="10dp"
android:padding="10dp"
android:elevation="4dp"
android:background="@color/colorPrimary"
android:textColor="@color/white"
android:text="In a land long ago and far far away."/>
</RelativeLayout>
</LinearLayout>
</ScrollView>
</RelativeLayout>

View File

@@ -1,7 +1,6 @@
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/black"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -11,20 +10,5 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"/>
<com.zl.reik.dilatingdotsprogressbar.DilatingDotsProgressBar
android:id="@+id/progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:radius="5dp"
android:elevation="8dp"
android:color="@color/white"
app:dd_numDots="10"
app:dd_scaleMultiplier="2"
app:dd_animationDuration="250"
app:dd_horizontalSpacing="10dp"
/>
</RelativeLayout>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 373 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 468 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 941 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -3,4 +3,5 @@
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="fab_margin">16dp</dimen>
<dimen name="text_margin">16dp</dimen>
</resources>