一.创建PhotoGallery应用
1.创建PhotoGallery项目
2.单击Next按钮,让应用向导创建一个名为PhotoGalleryActivity的空activity。
复制24章项目中的SingleFragmentActivity.java和activity_fragment.xml到当前项目中备用。
3.PhotoGalleryActivity.java的调整
输入以下代码
public class PhotoGalleryActivity extends SingleFragmentActivity {
@Override
protected Fragment creatFragment() {
return PhotoGalleryFragment.newInsance();
}
}
4.创建fragment_photo_gallery.xml文件
输入以下代码
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/photo_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.bignerdranch.android.photogallery.PhotoGalleryActivity"/>
5.新建PhotoGalleryFragment.java
输入如下代码
public class PhotoGalleryFragment extends Fragment {
private RecyclerView mPhtoRecyclerView;
public static PhotoGalleryFragment newInstance() {
return new PhotoGalleryFragment();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_photo_gallery,container,false);
mPhtoRecyclerView = (RecyclerView) v.findViewById(R.id.photo_recycler_view);
mPhtoRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(),3));
return v;
}
}
6.新建FlickrFetchr.java
输入代码如下:
public class FlickrFetchr {
public byte[] getUrlBytes(String urlSpec) throws IOException {
URL url = new URL(urlSpec);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
try{
ByteArrayOutputStream out = new ByteArrayOutputStream();
InputStream in = connection.getInputStream();
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
throw new IOException(connection.getResponseMessage() +
":with" +
urlSpec);
}
int bytesRead = 0;
byte[] buffer = new byte[1024];
while ((bytesRead = in.read(buffer)) > 0) {
out.write(buffer,0,bytesRead);
}
out.close();
return out.toByteArray();
}
finally {
connection.disconnect();
}
}
public String getUrlString(String urlSpec) throws IOException {
return new String(getUrlBytes(urlSpec));
}
}
6.使用AsyncTask在后台线程上运行代码,在PhotoGalleryFragment.java中输入以下代码。
~~public class PhotoGalleryFragment extends Fragment {~~
private static final String TAG = "PhotoGalleryFragment";
~~private RecyclerView mPhtoRecyclerView;~~
~~public static PhotoGalleryFragment newInstance() {
return new PhotoGalleryFragment();~~
~~}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);~~
new FetchItemsTask().execute();
...
private class FetchItemsTask extends AsyncTask<Void,Void,Void> {
@Override
protected Void doInBackground(Void...params) {
try {
String result = new FlickrFetchr()
.getUrlString("https://www.bignerdranch.com");
Log.e(TAG, "Failed to fetch URL:", ioe);
}
return null;
}
}
7.线程与主线程,对FlickrFetchr.java添加一些常量
代码如下:
~~public class FlickrFetchr {~~
private static final String TAG ="FlickrFetchr";
private static final String API_KEY ="yourApiKeyHere";
...
public void fetchItems() {
try {
String url = Uri.parse("https://api.flickr.com/services/rest")
.buildUpon()
.appendQueryParameter("method","flickr.photos.getRecent")
.appendQueryParameter("api_key",API_KEY)
.appendQueryParameter("format","json")
.appendQueryParameter("nojsoncallback","1")
.appendQueryParameter("extras","url_s")
.build().toString();
String jsonString =getUrlString(url);
Log.i(TAG,"Received JSON:" + jsonString);
} catch (IOException ioe) {
Log.e(TAG,"Failed to fetch items",ioe);
}
}
8.对PhotoGalleryFragment.java进行调整
private class FetchItemsTask extends AsyncTask<Void,Void,Void> {
@Override
protected Void doInBackground(Void...params) {
~~try {
String result = new FlickrFetchr()
.getUrlString("https://www.bignerdranch.com");
Log.e(TAG, "Failed to fetch URL:", ioe);
}~~
new FlickrFetchr().fetchItems();
return null;
}
9.对GalleryItem.java创建模型对象类
代码如下:
private String mCaption;
private String mId;
private String mUlr;
@Override
public String toString() {
return mCaption;
}
10.解析JSON数据(FlickrFetchr.java)
代码如下:
~~String jsonString =getUrlString(url);
Log.i(TAG,"Received JSON:" + jsonString);~~
JSONObject jsonBody = new JSONObject(jsonString);
~~} catch (IOException ioe) {
Log.e(TAG,"Failed to fetch items",ioe);~~
} catch (JSONException je){
Log,e(TAG,"Failed to parse JSON", je);
}
10.解析Flickr图片(FlickrFetchr.java)
~~Log,e(TAG,"Failed to parse JSON", je);
}
}~~
private void parseItems(List<GalleryItem>items,JSONObject jsonBody)
throws IOException,JSONException{
JSONObject photosJsonObject = jsonBody.getJSONObject("photos");
JSONArray photoJsonArray =photosJsonObject.getJSONArray("photo");
for (int i =0;i< photoJsonArray.length();i++) {
JSONObject photoJsonObject = photoJsonArray.getJSONObject(i);
GalleryItem item =new GalleryItem();
item.setId(photoJsonObject.getString("id"));
item.setCaption(photoJsonObject.getString("title"));
if (!photoJsonObject.has("url_s")) {
continue;
}
item.setUrl(photoJsonObject.getString("url_s"));
item.add(item);
}
11.调用parseItems方法(FlickrFetchr.java)
public ~~void~~ List<GalleryItem> fetchItems() {
List<GalleryItem> items =new ArrayList<>();
~~JSONObject jsonBody = new JSONObject(jsonString);~~
parseItems(items,jsonBody);
~~} catch (IOException ioe) {
Log.e(TAG,"Failed to fetch items",ioe);
} catch (JSONException je){
Log,e(TAG,"Failed to parse JSON", je);
}~~
return items;
12.从AsyncTask回到主线程(PhotoGalleryFragment.java)
~~return v;~~
}
private class PhotoHolder extends RecyclerView.ViewHolder {
private TextView mTitleTextView;
public PhotoHolder(View itemView){
super(itemView);
mTitleTextView =(TextView) itemView;
}
public void bindGalleryItem(GalleryItem item) {
mTitleTextView.setText(item.toString());
~~public void bindGalleryItem(GalleryItem item) {
mTitleTextView.setText(item.toString());
}
}~~
private class PhotoAdapter extends RecyclerView.Adapter<PhotoHolder> {
private List<GalleryItem> mGalleryItems;
public PhotoAdapter(List<GalleryItem> galleryItems) {
mGalleryItems = galleryItems;
}
@Override
public PhotoHolder onCreateViewHolder(ViewGroup viewGroup,int viewType) {
TextView textView=new TextView(getActivity());
return new PhotoHolder(textView);
}
@Override
public void onBindViewHolder(PhotoHolder photoHolder,int position) {
GalleryItem galleryItem=mGalleryItems.get(position);
photoHolder.bindGalleryItem(galleryItem);
}
@Override
public int getItemCount() {
return mGalleryItems.size();
}
13.实现setupAdapter方法(PhotoGalleryFragment.java)
~~private static final String TAG = "PhotoGalleryFragment";
private RecyclerView mPhtoRecyclerView;~~
private List<GalleryItem>mItems =new ArrayList<>();
setupAdapter();
~~return v;~~
}
private void setupAdapter() {
if (isAdded()) {
mPhtoRecyclerView.setAdapter(new PhotoAdapter(mItems));
}
}
14.添加adapter更新代码(PhotoGalleryFragment.java)
private class FetchItemsTask extends AsyncTask<Void,Void,~~void~~ list<GalleryItem>> {
@Override
protected ~~void~~ List<GalleryItem> doInBackground(Void...params) {
return new FlickrFetchr().fetchItems();
~~return null;~~
}
@Override
protected void onPostExecute(List<GalleryItem> items) {
mItems =items;
setupAdapter();
}
注:由于学习要求,本教程好多都用到前面章节的一些设置,所以好多文件会出错,结果就出不来,所以本人就不发布结果出来了。
成功之后的结果大致为这样