如何在 Android Studio 中创建壁纸应用程序?
几乎所有 Android 设备的主屏幕上都设置了壁纸。为了将此壁纸设置到屏幕上,许多 Android 设备都提供了一个壁纸应用程序,我们可以在其中根据各种类别浏览不同类型的壁纸。在本文中,我们将着眼于在 Android Studio 中的 Android 设备中构建一个类似的应用程序。
我们将在本文中构建什么?
我们将构建一个简单的壁纸应用程序,我们将在其中添加基于各种类别过滤壁纸的功能。除此之外,我们还将添加一个搜索栏来根据用户搜索查询搜索壁纸。下面是视频,我们将在其中看到我们将在本文中构建的内容。请注意,我们将使用Java语言来实现这个项目。
分步实施
第 1 步:创建一个新项目
要在 Android Studio 中创建新项目,请参阅如何在 Android Studio 中创建/启动新项目。请注意,选择Java作为编程语言。
第 2 步:在进入编码部分之前,您必须先做一些准备工作
转到app > res > values > colors.xml部分并为您的应用设置颜色。
XML
#0F9D58
#0F9D58
#0F9D58
#0F9D58
#FF018786
#FF000000
#FFFFFFFF
#292D36
#272B33
#22252D
#021853
#ffa500
XML
XML
Java
public class CategoryRVModal {
// creating variable font category
// and image url on below line.
private String category;
private String imgUrl;
public CategoryRVModal(String category, String imgUrl) {
this.category = category;
this.imgUrl = imgUrl;
}
// creating a constructor, getter and setter methods.
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getImgUrl() {
return imgUrl;
}
public void setImgUrl(String imgUrl) {
this.imgUrl = imgUrl;
}
}
XML
XML
XML
XML
Java
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
public class WallpaperRVAdapter extends RecyclerView.Adapter {
// creating variables for array list and context.
private ArrayList wallPaperList;
private Context context;
// creating a constructor.
public WallpaperRVAdapter(ArrayList wallPaperList, Context context) {
this.wallPaperList = wallPaperList;
this.context = context;
}
@NonNull
@Override
public WallpaperRVAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// inflating our layout file on below line.
View view = LayoutInflater.from(context).inflate(R.layout.wallpaper_rv_item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull WallpaperRVAdapter.ViewHolder holder, int position) {
// setting data to all our views.
Glide.with(context).load(wallPaperList.get(position)).into(holder.wallpaperIV);
// adding on click listener to item view.
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// passing data through intent on below line.
Intent i = new Intent(context, WallpaperActivity.class);
i.putExtra("imgUrl", wallPaperList.get(position));
context.startActivity(i);
}
});
}
@Override
public int getItemCount() {
return wallPaperList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
// creating variables for our views
// which are created in layout file.
private CardView imageCV;
private ImageView wallpaperIV;
public ViewHolder(@NonNull View itemView) {
super(itemView);
// initializing all the variables.
wallpaperIV = itemView.findViewById(R.id.idIVWallpaper);
imageCV = itemView.findViewById(R.id.idCVWallpaper);
}
}
}
Java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
public class CategoryRVAdapter extends RecyclerView.Adapter {
// creating variables for
// array list and context and interface.
private ArrayList categoryRVModals;
private Context context;
private CategoryClickInterface categoryClickInterface;
// creating a constructor.
public CategoryRVAdapter(ArrayList categoryRVModals, Context context, CategoryClickInterface categoryClickInterface) {
this.categoryRVModals = categoryRVModals;
this.context = context;
this.categoryClickInterface = categoryClickInterface;
}
@NonNull
@Override
public CategoryRVAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// inflating our layout file on below line.
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.category_rv_item, parent, false);
return new CategoryRVAdapter.ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull CategoryRVAdapter.ViewHolder holder, int position) {
// setting data to all our views.
CategoryRVModal modal = categoryRVModals.get(position);
holder.categoryTV.setText(modal.getCategory());
if (!modal.getImgUrl().isEmpty()) {
Glide.with(context).load(modal.getImgUrl()).into(holder.categoryIV);
} else {
holder.categoryIV.setImageResource(R.drawable.ic_launcher_background);
}
// adding on click listener to item view on below line.
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// passing position with interface.
categoryClickInterface.onCategoryClick(position);
}
});
}
@Override
public int getItemCount() {
return categoryRVModals.size();
}
// creating an interface on below line.
public interface CategoryClickInterface {
void onCategoryClick(int position);
}
public class ViewHolder extends RecyclerView.ViewHolder {
// creating variables on below line.
private TextView categoryTV;
private ImageView categoryIV;
public ViewHolder(@NonNull View itemView) {
super(itemView);
// initializing all variables on below line.
categoryIV = itemView.findViewById(R.id.idIVCategory);
categoryTV = itemView.findViewById(R.id.idTVCategory);
}
}
}
XML
Java
import android.app.WallpaperManager;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.shashank.sony.fancytoastlib.FancyToast;
import java.io.IOException;
public class WallpaperActivity extends AppCompatActivity {
// on below line we are creating variables
// for imageview and wallpaper manager
WallpaperManager wallpaperManager;
ImageView image;
String url;
private ProgressBar loadingPB;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wallpaper);
// initializing all variables on below line.
url = getIntent().getStringExtra("imgUrl");
image = findViewById(R.id.image);
loadingPB = findViewById(R.id.idPBLoading);
// calling glide to load image from url on below line.
Glide.with(this).load(url).listener(new RequestListener() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
// making progress bar visibility
// to gone on below line.
loadingPB.setVisibility(View.GONE);
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
// making progress bar visibility to gone
// on below line when image is ready.
loadingPB.setVisibility(View.GONE);
return false;
}
}).into(image);
wallpaperManager = WallpaperManager.getInstance(getApplicationContext());
Button setWallpaper = findViewById(R.id.idBtnSetWallpaper);
// on below line we are adding on click
// listener to our set wallpaper button.
setWallpaper.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Glide.with(WallpaperActivity.this)
.asBitmap().load(url)
.listener(new RequestListener() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object o, Target target, boolean b) {
Toast.makeText(WallpaperActivity.this, "Fail to load image..", Toast.LENGTH_SHORT).show();
return false;
}
@Override
public boolean onResourceReady(Bitmap bitmap, Object o, Target target, DataSource dataSource, boolean b) {
// on below line we are setting wallpaper using
// wallpaper manager on below line.
try {
wallpaperManager.setBitmap(bitmap);
Toast.makeText(WallpaperActivity.this, "Wallpaper Set to Home screen.", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
// on below line we are handling exception.
Toast.makeText(WallpaperActivity.this, "Fail to set wallpaper", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
return false;
}
}
).submit();
// displaying custom toast on below line.
FancyToast.makeText(WallpaperActivity.this, "Wallpaper Set to Home Screen", FancyToast.LENGTH_LONG, FancyToast.SUCCESS, false).show();
}
});
}
}
Java
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class MainActivity extends AppCompatActivity implements CategoryRVAdapter.CategoryClickInterface {
// creating variables for recyclerview,
// progress bar, adapter and array list,
// edittext and others.
private RecyclerView categoryRV, wallpaperRV;
private ProgressBar loadingPB;
private ArrayList categoryRVModals;
private ArrayList wallpaperArrayList;
private CategoryRVAdapter categoryRVAdapter;
private WallpaperRVAdapter wallpaperRVAdapter;
private EditText searchEdt;
private ImageView searchIV;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_screen);
// initializing all variables on below line.
categoryRV = findViewById(R.id.idRVCategories);
wallpaperRV = findViewById(R.id.idRVWallpapers);
searchEdt = findViewById(R.id.idEdtSearch);
searchIV = findViewById(R.id.idIVSearch);
loadingPB = findViewById(R.id.idPBLoading);
wallpaperArrayList = new ArrayList<>();
categoryRVModals = new ArrayList<>();
// creating a layout manager for
// recycler view which is our category.
LinearLayoutManager manager1 = new LinearLayoutManager(MainActivity.this, RecyclerView.HORIZONTAL, false);
// initializing our adapter class on below line.
wallpaperRVAdapter = new WallpaperRVAdapter(wallpaperArrayList, this);
categoryRVAdapter = new CategoryRVAdapter(categoryRVModals, this, this);
// setting layout manager to our
// category recycler view as horizontal.
categoryRV.setLayoutManager(manager1);
categoryRV.setAdapter(categoryRVAdapter);
// creating a grid layout manager
// for our wallpaper recycler view.
GridLayoutManager layoutManager = new GridLayoutManager(this, 2);
// setting layout manager and
// adapter to our recycler view.
wallpaperRV.setLayoutManager(layoutManager);
wallpaperRV.setAdapter(wallpaperRVAdapter);
// on below line we are calling method to
// get categories to add data in array list.
getCategories();
// on below line we are calling get wallpaper
// method to get data in wallpaper array list.
getWallpapers();
// on below line we are adding on click listener
// for search image view on below line.
searchIV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// inside on click method we are getting data from
// our search edittext and validating if the input field is empty or not.
String searchStr = searchEdt.getText().toString();
if (searchStr.isEmpty()) {
Toast.makeText(MainActivity.this, "Please enter something to search", Toast.LENGTH_SHORT).show();
} else {
// on below line we are calling a get wallpaper
// method to get wallpapers by category.
getWallpapersByCategory(searchStr);
}
}
});
}
// on below line we are creating a method
// to get the wallpaper by category.
private void getWallpapersByCategory(String category) {
// on below line we are
// clearing our array list.
wallpaperArrayList.clear();
// on below line we are making visibility
// of our progress bar as gone.
loadingPB.setVisibility(View.VISIBLE);
// on below line we are creating a string
// variable for our url and adding url to it.
String url = "https://api.pexels.com/v1/search?query=" + category + "&per_page=30&page=1";
// on below line we are creating a
// new variable for our request queue.
RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
// on below line we are making a json object
// request to get the data from url .
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener() {
@Override
public void onResponse(JSONObject response) {
// on below line we are extracting the data from our
// response and passing it to our array list.
try {
loadingPB.setVisibility(View.GONE);
// on below line we are extracting json data.
JSONArray photos = response.getJSONArray("photos");
for (int i = 0; i < photos.length(); i++) {
JSONObject photoObj = photos.getJSONObject(i);
String imgUrl = photoObj.getJSONObject("src").getString("portrait");
// on below line we are passing
// data to our array list
wallpaperArrayList.add(imgUrl);
}
// here we are notifying adapter
// that data has changed in our list.
wallpaperRVAdapter.notifyDataSetChanged();
} catch (JSONException e) {
// handling json exception
// on below line.
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// displaying a simple toast message on error response.
Toast.makeText(MainActivity.this, "Fail to get data..", Toast.LENGTH_SHORT).show();
}
}) {
@Override
public Map getHeaders() {
// in this method passing headers as
// key along with value as API keys.
HashMap headers = new HashMap<>();
headers.put("Authorization", "Enter your key");
// at last returning headers.
return headers;
}
};
queue.add(jsonObjectRequest);
}
private void getWallpapers() {
// on below line we are
// clearing our array list.
wallpaperArrayList.clear();
// changing visibility of our
// progress bar to gone.
loadingPB.setVisibility(View.VISIBLE);
// creating a variable for our url.
String url = "https://api.pexels.com/v1/curated?per_page=30&page=1";
// on below line we are creating a
// new variable for our request queue.
RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
// on below line we are making a json
// object request to get the data from url .
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener() {
@Override
public void onResponse(JSONObject response) {
// on below line we are extracting the data from
// our response and passing it to our array list.
loadingPB.setVisibility(View.GONE);
try {
// on below line we are extracting json data.
JSONArray photos = response.getJSONArray("photos");
for (int i = 0; i < photos.length(); i++) {
JSONObject photoObj = photos.getJSONObject(i);
String imgUrl = photoObj.getJSONObject("src").getString("portrait");
// on below line we are passing
// data to our array list
wallpaperArrayList.add(imgUrl);
}
wallpaperRVAdapter.notifyDataSetChanged();
} catch (JSONException e) {
// handling json exception
// on below line.
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// displaying a toast message on error response.
Toast.makeText(MainActivity.this, "Fail to get data..", Toast.LENGTH_SHORT).show();
}
}) {
@Override
public Map getHeaders() {
// in this method passing headers as
// key along with value as API keys.
HashMap headers = new HashMap<>();
headers.put("Authorization", "Enter your key");
// at last returning headers.
return headers;
}
};
queue.add(jsonObjectRequest);
}
private void getCategories() {
// on below lines we are adding data to our category array list.
categoryRVModals.add(new CategoryRVModal("Technology", "https://images.unsplash.com/photo-1526374965328-7f61d4dc18c5?ixid=MnwxMjA3fDB8MHxzZWFyY2h8MTJ8fHRlY2hub2xvZ3l8ZW58MHx8MHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60"));
categoryRVModals.add(new CategoryRVModal("Programming", "https://images.unsplash.com/photo-1542831371-29b0f74f9713?ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8cHJvZ3JhbW1pbmd8ZW58MHx8MHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60"));
categoryRVModals.add(new CategoryRVModal("Nature", "https://images.pexels.com/photos/2387873/pexels-photo-2387873.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"));
categoryRVModals.add(new CategoryRVModal("Travel", "https://images.pexels.com/photos/672358/pexels-photo-672358.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"));
categoryRVModals.add(new CategoryRVModal("Architecture", "https://images.pexels.com/photos/256150/pexels-photo-256150.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"));
categoryRVModals.add(new CategoryRVModal("Arts", "https://images.pexels.com/photos/1194420/pexels-photo-1194420.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"));
categoryRVModals.add(new CategoryRVModal("Music", "https://images.pexels.com/photos/4348093/pexels-photo-4348093.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"));
categoryRVModals.add(new CategoryRVModal("Abstract", "https://images.pexels.com/photos/2110951/pexels-photo-2110951.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"));
categoryRVModals.add(new CategoryRVModal("Cars", "https://images.pexels.com/photos/3802510/pexels-photo-3802510.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"));
categoryRVModals.add(new CategoryRVModal("Flowers", "https://images.pexels.com/photos/1086178/pexels-photo-1086178.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"));
}
@Override
public void onCategoryClick(int position) {
// on below line we are getting category from our
// array list and calling a method
// to get wallpapers by category.
String category = categoryRVModals.get(position).getCategory();
getWallpapersByCategory(category);
}
}
第 3 步:在 build.gradle 文件中添加依赖项
转到Gradle Scripts > build.gradle (Module: app)部分并导入以下依赖项,然后单击上面弹出窗口中的“立即同步”。
implementation 'com.github.bumptech.glide:glide:4.11.0'
implementation 'com.android.volley:volley:1.1.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
implementation 'com.github.Shashank02051997:FancyToast-Android:0.1.8'
导航到app > Gradle Scripts > build.gradle(Project level) ,在这个文件中,我们必须在 allProjects 部分添加 mavenCentral。
allprojects {
repositories {
google()
mavenCentral()
// add below line
maven { url "https://jitpack.io" }
jcenter()
}
}
添加此依赖项后,我们只需同步我们的项目即可安装所有依赖项的包。
第 4 步:在 AndroidManifest.xml 文件中添加 Internet 权限
导航到应用程序 > AndroidManifest.xml文件并在其中添加以下代码行。
XML
第 5 步:使用 activity_main.xml 文件
导航到app > res > layout > activity_main.xml并将以下代码添加到该文件。下面是activity_main.xml文件的代码。
XML
第 6 步:创建一个新的Java模态类来存储类别的数据
导航到应用程序 > Java > 您的应用程序的包名称 > 右键单击它 > 新建 > Java类并将其命名为CategoryRVModal添加以下代码。代码中添加了注释以更详细地了解。
Java
public class CategoryRVModal {
// creating variable font category
// and image url on below line.
private String category;
private String imgUrl;
public CategoryRVModal(String category, String imgUrl) {
this.category = category;
this.imgUrl = imgUrl;
}
// creating a constructor, getter and setter methods.
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getImgUrl() {
return imgUrl;
}
public void setImgUrl(String imgUrl) {
this.imgUrl = imgUrl;
}
}
第 7 步:创建可绘制文件
我们将创建两个可绘制文件,一个用于我们的按钮背景。要创建此文件,请导航到应用程序 > res > drawable > 右键单击它 > 新建并将其命名为button_back并添加以下代码。代码中添加了注释以更详细地了解。
XML
之后,我们将为搜索栏背景创建一个可绘制文件。同样,创建另一个可绘制文件并将其命名为search_back并将以下代码添加到其中。
XML
第 8 步:为 category_rv_item 创建布局文件
导航到app > res > layout > category_rv_item并将以下代码添加到其中。代码中添加了注释以更详细地了解。
XML
步骤 9:为 Wallpaper RecyclerView 中的项目创建布局文件
导航到应用程序 > res > 布局 > 右键单击它 > 新建 > 布局资源文件并将其命名为wallpaper_rv_item并添加以下代码。代码中添加了注释以更详细地了解。
XML
第 10 步:创建一个 Adapter 类,用于为 RecyclerView 的项设置数据
导航到应用程序 > Java > 您的应用程序的包名称 > 右键单击它 > 新建 > Java类并将其命名为WallpaperRVAdapter并将以下代码添加到其中。代码中添加了注释以更详细地了解。
Java
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
public class WallpaperRVAdapter extends RecyclerView.Adapter {
// creating variables for array list and context.
private ArrayList wallPaperList;
private Context context;
// creating a constructor.
public WallpaperRVAdapter(ArrayList wallPaperList, Context context) {
this.wallPaperList = wallPaperList;
this.context = context;
}
@NonNull
@Override
public WallpaperRVAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// inflating our layout file on below line.
View view = LayoutInflater.from(context).inflate(R.layout.wallpaper_rv_item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull WallpaperRVAdapter.ViewHolder holder, int position) {
// setting data to all our views.
Glide.with(context).load(wallPaperList.get(position)).into(holder.wallpaperIV);
// adding on click listener to item view.
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// passing data through intent on below line.
Intent i = new Intent(context, WallpaperActivity.class);
i.putExtra("imgUrl", wallPaperList.get(position));
context.startActivity(i);
}
});
}
@Override
public int getItemCount() {
return wallPaperList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
// creating variables for our views
// which are created in layout file.
private CardView imageCV;
private ImageView wallpaperIV;
public ViewHolder(@NonNull View itemView) {
super(itemView);
// initializing all the variables.
wallpaperIV = itemView.findViewById(R.id.idIVWallpaper);
imageCV = itemView.findViewById(R.id.idCVWallpaper);
}
}
}
第 11 步:为我们的 Category RecyclerView 创建一个 Adapter 类
导航到应用程序 > Java > 您的应用程序的包名称 > 右键单击它 > 新建 > Java类并将其命名为CategoryRVAdapter并将以下代码添加到其中。代码中添加了注释以更详细地了解。
Java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
public class CategoryRVAdapter extends RecyclerView.Adapter {
// creating variables for
// array list and context and interface.
private ArrayList categoryRVModals;
private Context context;
private CategoryClickInterface categoryClickInterface;
// creating a constructor.
public CategoryRVAdapter(ArrayList categoryRVModals, Context context, CategoryClickInterface categoryClickInterface) {
this.categoryRVModals = categoryRVModals;
this.context = context;
this.categoryClickInterface = categoryClickInterface;
}
@NonNull
@Override
public CategoryRVAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// inflating our layout file on below line.
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.category_rv_item, parent, false);
return new CategoryRVAdapter.ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull CategoryRVAdapter.ViewHolder holder, int position) {
// setting data to all our views.
CategoryRVModal modal = categoryRVModals.get(position);
holder.categoryTV.setText(modal.getCategory());
if (!modal.getImgUrl().isEmpty()) {
Glide.with(context).load(modal.getImgUrl()).into(holder.categoryIV);
} else {
holder.categoryIV.setImageResource(R.drawable.ic_launcher_background);
}
// adding on click listener to item view on below line.
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// passing position with interface.
categoryClickInterface.onCategoryClick(position);
}
});
}
@Override
public int getItemCount() {
return categoryRVModals.size();
}
// creating an interface on below line.
public interface CategoryClickInterface {
void onCategoryClick(int position);
}
public class ViewHolder extends RecyclerView.ViewHolder {
// creating variables on below line.
private TextView categoryTV;
private ImageView categoryIV;
public ViewHolder(@NonNull View itemView) {
super(itemView);
// initializing all variables on below line.
categoryIV = itemView.findViewById(R.id.idIVCategory);
categoryTV = itemView.findViewById(R.id.idTVCategory);
}
}
}
第 12 步:创建一个新 Activity 以显示单个壁纸
导航到应用程序 > Java > 你的应用程序的包名称 > 右键单击它 > 新建 > 活动 > 选择 Empty Activity并将其命名为WallpaperActivity ,现在我们将转向activity_wallpaper.xml的工作。
第 13 步:使用 activity_wallpaper.xml 文件
导航到app > res > layout > activity_wallpaper.xml并将以下代码添加到其中。代码中添加了注释以更详细地了解。
XML
第 14 步:使用 WallpaperActivity。Java
导航到应用程序 > Java > 您的应用程序的包名称 > WallpaperActivity。 Java文件并在其中添加以下代码。代码中添加了注释以更详细地了解。
Java
import android.app.WallpaperManager;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.shashank.sony.fancytoastlib.FancyToast;
import java.io.IOException;
public class WallpaperActivity extends AppCompatActivity {
// on below line we are creating variables
// for imageview and wallpaper manager
WallpaperManager wallpaperManager;
ImageView image;
String url;
private ProgressBar loadingPB;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wallpaper);
// initializing all variables on below line.
url = getIntent().getStringExtra("imgUrl");
image = findViewById(R.id.image);
loadingPB = findViewById(R.id.idPBLoading);
// calling glide to load image from url on below line.
Glide.with(this).load(url).listener(new RequestListener() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
// making progress bar visibility
// to gone on below line.
loadingPB.setVisibility(View.GONE);
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
// making progress bar visibility to gone
// on below line when image is ready.
loadingPB.setVisibility(View.GONE);
return false;
}
}).into(image);
wallpaperManager = WallpaperManager.getInstance(getApplicationContext());
Button setWallpaper = findViewById(R.id.idBtnSetWallpaper);
// on below line we are adding on click
// listener to our set wallpaper button.
setWallpaper.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Glide.with(WallpaperActivity.this)
.asBitmap().load(url)
.listener(new RequestListener() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object o, Target target, boolean b) {
Toast.makeText(WallpaperActivity.this, "Fail to load image..", Toast.LENGTH_SHORT).show();
return false;
}
@Override
public boolean onResourceReady(Bitmap bitmap, Object o, Target target, DataSource dataSource, boolean b) {
// on below line we are setting wallpaper using
// wallpaper manager on below line.
try {
wallpaperManager.setBitmap(bitmap);
Toast.makeText(WallpaperActivity.this, "Wallpaper Set to Home screen.", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
// on below line we are handling exception.
Toast.makeText(WallpaperActivity.this, "Fail to set wallpaper", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
return false;
}
}
).submit();
// displaying custom toast on below line.
FancyToast.makeText(WallpaperActivity.this, "Wallpaper Set to Home Screen", FancyToast.LENGTH_LONG, FancyToast.SUCCESS, false).show();
}
});
}
}
第 15 步:为 Pixels API 生成 API 密钥
要生成使用 Pexels API 的 API,我们只需在此处访问 Pexels 站点。访问此站点后,我们只需在此站点上注册并创建一个帐户。创建新帐户后,您只需登录到您的帐户即可。登录到您的帐户后。您将看到以下屏幕。
在此屏幕中,我们只需单击帐户选项箭头,然后只需选择图像和视频 API 选项即可查看我们的 API 密钥。单击该选项后,将打开一个新屏幕,我们只需单击您的 API 密钥选项即可获取我们的 API 密钥。然后您将看到您的 API,如下所示。
现在我们将在我们的应用程序中使用这个 API 密钥。
第 16 步:使用 MainActivity。Java
转到MainActivity。 Java文件并参考以下代码。下面是MainActivity 的代码。 Java文件。代码中添加了注释以更详细地理解代码。
Java
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class MainActivity extends AppCompatActivity implements CategoryRVAdapter.CategoryClickInterface {
// creating variables for recyclerview,
// progress bar, adapter and array list,
// edittext and others.
private RecyclerView categoryRV, wallpaperRV;
private ProgressBar loadingPB;
private ArrayList categoryRVModals;
private ArrayList wallpaperArrayList;
private CategoryRVAdapter categoryRVAdapter;
private WallpaperRVAdapter wallpaperRVAdapter;
private EditText searchEdt;
private ImageView searchIV;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_screen);
// initializing all variables on below line.
categoryRV = findViewById(R.id.idRVCategories);
wallpaperRV = findViewById(R.id.idRVWallpapers);
searchEdt = findViewById(R.id.idEdtSearch);
searchIV = findViewById(R.id.idIVSearch);
loadingPB = findViewById(R.id.idPBLoading);
wallpaperArrayList = new ArrayList<>();
categoryRVModals = new ArrayList<>();
// creating a layout manager for
// recycler view which is our category.
LinearLayoutManager manager1 = new LinearLayoutManager(MainActivity.this, RecyclerView.HORIZONTAL, false);
// initializing our adapter class on below line.
wallpaperRVAdapter = new WallpaperRVAdapter(wallpaperArrayList, this);
categoryRVAdapter = new CategoryRVAdapter(categoryRVModals, this, this);
// setting layout manager to our
// category recycler view as horizontal.
categoryRV.setLayoutManager(manager1);
categoryRV.setAdapter(categoryRVAdapter);
// creating a grid layout manager
// for our wallpaper recycler view.
GridLayoutManager layoutManager = new GridLayoutManager(this, 2);
// setting layout manager and
// adapter to our recycler view.
wallpaperRV.setLayoutManager(layoutManager);
wallpaperRV.setAdapter(wallpaperRVAdapter);
// on below line we are calling method to
// get categories to add data in array list.
getCategories();
// on below line we are calling get wallpaper
// method to get data in wallpaper array list.
getWallpapers();
// on below line we are adding on click listener
// for search image view on below line.
searchIV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// inside on click method we are getting data from
// our search edittext and validating if the input field is empty or not.
String searchStr = searchEdt.getText().toString();
if (searchStr.isEmpty()) {
Toast.makeText(MainActivity.this, "Please enter something to search", Toast.LENGTH_SHORT).show();
} else {
// on below line we are calling a get wallpaper
// method to get wallpapers by category.
getWallpapersByCategory(searchStr);
}
}
});
}
// on below line we are creating a method
// to get the wallpaper by category.
private void getWallpapersByCategory(String category) {
// on below line we are
// clearing our array list.
wallpaperArrayList.clear();
// on below line we are making visibility
// of our progress bar as gone.
loadingPB.setVisibility(View.VISIBLE);
// on below line we are creating a string
// variable for our url and adding url to it.
String url = "https://api.pexels.com/v1/search?query=" + category + "&per_page=30&page=1";
// on below line we are creating a
// new variable for our request queue.
RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
// on below line we are making a json object
// request to get the data from url .
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener() {
@Override
public void onResponse(JSONObject response) {
// on below line we are extracting the data from our
// response and passing it to our array list.
try {
loadingPB.setVisibility(View.GONE);
// on below line we are extracting json data.
JSONArray photos = response.getJSONArray("photos");
for (int i = 0; i < photos.length(); i++) {
JSONObject photoObj = photos.getJSONObject(i);
String imgUrl = photoObj.getJSONObject("src").getString("portrait");
// on below line we are passing
// data to our array list
wallpaperArrayList.add(imgUrl);
}
// here we are notifying adapter
// that data has changed in our list.
wallpaperRVAdapter.notifyDataSetChanged();
} catch (JSONException e) {
// handling json exception
// on below line.
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// displaying a simple toast message on error response.
Toast.makeText(MainActivity.this, "Fail to get data..", Toast.LENGTH_SHORT).show();
}
}) {
@Override
public Map getHeaders() {
// in this method passing headers as
// key along with value as API keys.
HashMap headers = new HashMap<>();
headers.put("Authorization", "Enter your key");
// at last returning headers.
return headers;
}
};
queue.add(jsonObjectRequest);
}
private void getWallpapers() {
// on below line we are
// clearing our array list.
wallpaperArrayList.clear();
// changing visibility of our
// progress bar to gone.
loadingPB.setVisibility(View.VISIBLE);
// creating a variable for our url.
String url = "https://api.pexels.com/v1/curated?per_page=30&page=1";
// on below line we are creating a
// new variable for our request queue.
RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
// on below line we are making a json
// object request to get the data from url .
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener() {
@Override
public void onResponse(JSONObject response) {
// on below line we are extracting the data from
// our response and passing it to our array list.
loadingPB.setVisibility(View.GONE);
try {
// on below line we are extracting json data.
JSONArray photos = response.getJSONArray("photos");
for (int i = 0; i < photos.length(); i++) {
JSONObject photoObj = photos.getJSONObject(i);
String imgUrl = photoObj.getJSONObject("src").getString("portrait");
// on below line we are passing
// data to our array list
wallpaperArrayList.add(imgUrl);
}
wallpaperRVAdapter.notifyDataSetChanged();
} catch (JSONException e) {
// handling json exception
// on below line.
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// displaying a toast message on error response.
Toast.makeText(MainActivity.this, "Fail to get data..", Toast.LENGTH_SHORT).show();
}
}) {
@Override
public Map getHeaders() {
// in this method passing headers as
// key along with value as API keys.
HashMap headers = new HashMap<>();
headers.put("Authorization", "Enter your key");
// at last returning headers.
return headers;
}
};
queue.add(jsonObjectRequest);
}
private void getCategories() {
// on below lines we are adding data to our category array list.
categoryRVModals.add(new CategoryRVModal("Technology", "https://images.unsplash.com/photo-1526374965328-7f61d4dc18c5?ixid=MnwxMjA3fDB8MHxzZWFyY2h8MTJ8fHRlY2hub2xvZ3l8ZW58MHx8MHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60"));
categoryRVModals.add(new CategoryRVModal("Programming", "https://images.unsplash.com/photo-1542831371-29b0f74f9713?ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8cHJvZ3JhbW1pbmd8ZW58MHx8MHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60"));
categoryRVModals.add(new CategoryRVModal("Nature", "https://images.pexels.com/photos/2387873/pexels-photo-2387873.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"));
categoryRVModals.add(new CategoryRVModal("Travel", "https://images.pexels.com/photos/672358/pexels-photo-672358.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"));
categoryRVModals.add(new CategoryRVModal("Architecture", "https://images.pexels.com/photos/256150/pexels-photo-256150.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"));
categoryRVModals.add(new CategoryRVModal("Arts", "https://images.pexels.com/photos/1194420/pexels-photo-1194420.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"));
categoryRVModals.add(new CategoryRVModal("Music", "https://images.pexels.com/photos/4348093/pexels-photo-4348093.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"));
categoryRVModals.add(new CategoryRVModal("Abstract", "https://images.pexels.com/photos/2110951/pexels-photo-2110951.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"));
categoryRVModals.add(new CategoryRVModal("Cars", "https://images.pexels.com/photos/3802510/pexels-photo-3802510.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"));
categoryRVModals.add(new CategoryRVModal("Flowers", "https://images.pexels.com/photos/1086178/pexels-photo-1086178.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"));
}
@Override
public void onCategoryClick(int position) {
// on below line we are getting category from our
// array list and calling a method
// to get wallpapers by category.
String category = categoryRVModals.get(position).getCategory();
getWallpapersByCategory(category);
}
}
现在运行您的应用程序并查看应用程序的输出。
Note: All drawable files used in the app are present in the drawable folder. Check out the project on below GitHub link.
GitHub链接: https://github.com/ChaitanyaMunje/Wallpaper-App
输出: