基于Bmob的Android资讯类app开发(一)
2017-04-17 21:01
375 查看
这个小app仅是为了熟悉Bmob和Android而开发的,一些很基础的东西,记录下来。
一、app介绍:
一个UFO、灵异事件和未解之谜相关兴趣的资讯展示和讨论社区。主页包括头条新闻、灵异事件资讯、未解之谜资讯、社区。前三部分结构完全一样,仅仅为了在ListView上展示Bmob的数据,社区功能可以发贴和评论,也是为了熟悉Bmob的数据操作。此外还包括注册和登录功能。个人中心界面仅作跳转(页面功能未实现)。
二、Bmob简介:
Bmob是什么?Bmob是一个后台管理程序,Bmob 为你提供了实时数据与文件存储功能,轻松实现应用“云与端”的数据连通。数据存储除了常规应用文本信息的存储,还可以存储图片、视频、音频、地理位置等信息。
此外数据服务还内置用户系统、即时通讯、权限控制等,开发者几行代码即可实现快速集成。
上面是官方介绍,简言之,Bmob就是一个云数据库,可以方便的管理数据,将数据加载到Android的app中,简化后台开发,很方便也很简单,适合于做毕业设计的同学们以及快速开发个人app,哈哈。
三、主页面设计
这个页面在第一篇文章中有详细的介绍。这里不再赘述。
Android选项卡TabLayout简单使用
四、导入Bmob sdk
这部分是使用Bmob的基本方法,建议转移到Bmob官网查看文档,文档非常详细。
文档地址:点击进入
五、ListView加载Bmob上的数据
1.list_item_card_main.xml ListView的item布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">
<ImageView
android:id="@+id/head_pic"
android:layout_width="100dp"
android:layout_height="120dp"
android:adjustViewBounds="true"
android:src="@drawable/logo"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:orientation="vertical">
<TextView
android:id="@+id/head_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:maxLines="2"
android:text="UFO之谜"
android:textColor="@color/black"
android:textSize="20sp"/>
<TextView
android:id="@+id/head_describe"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:maxLines="3"
android:text="UFO(Unidentified Flying Object ),不明飞行物是指不明来历、不明空间、不明结构、不明性质,但又漂浮、飞行在空中的物体。"
android:textColor="#666"
android:textSize="15sp"/>
</LinearLayout>
</LinearLayout>
2.list_head.xml 头条布局文件
ImageLoader.java
4.head.java 头条实体类
5.FirstFragment.java 头条主代码
这样就完成了头条的加载,可以从Bmob中更新数据,显示在app上。灵异事件和未解之谜的实现和头条一样,只需稍作修改,这里不再记录。下一篇会记录社区功能的实现。
一、app介绍:
一个UFO、灵异事件和未解之谜相关兴趣的资讯展示和讨论社区。主页包括头条新闻、灵异事件资讯、未解之谜资讯、社区。前三部分结构完全一样,仅仅为了在ListView上展示Bmob的数据,社区功能可以发贴和评论,也是为了熟悉Bmob的数据操作。此外还包括注册和登录功能。个人中心界面仅作跳转(页面功能未实现)。
二、Bmob简介:
Bmob是什么?Bmob是一个后台管理程序,Bmob 为你提供了实时数据与文件存储功能,轻松实现应用“云与端”的数据连通。数据存储除了常规应用文本信息的存储,还可以存储图片、视频、音频、地理位置等信息。
此外数据服务还内置用户系统、即时通讯、权限控制等,开发者几行代码即可实现快速集成。
上面是官方介绍,简言之,Bmob就是一个云数据库,可以方便的管理数据,将数据加载到Android的app中,简化后台开发,很方便也很简单,适合于做毕业设计的同学们以及快速开发个人app,哈哈。
三、主页面设计
这个页面在第一篇文章中有详细的介绍。这里不再赘述。
Android选项卡TabLayout简单使用
四、导入Bmob sdk
这部分是使用Bmob的基本方法,建议转移到Bmob官网查看文档,文档非常详细。
文档地址:点击进入
五、ListView加载Bmob上的数据
1.list_item_card_main.xml ListView的item布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">
<ImageView
android:id="@+id/head_pic"
android:layout_width="100dp"
android:layout_height="120dp"
android:adjustViewBounds="true"
android:src="@drawable/logo"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:orientation="vertical">
<TextView
android:id="@+id/head_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:maxLines="2"
android:text="UFO之谜"
android:textColor="@color/black"
android:textSize="20sp"/>
<TextView
android:id="@+id/head_describe"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:maxLines="3"
android:text="UFO(Unidentified Flying Object ),不明飞行物是指不明来历、不明空间、不明结构、不明性质,但又漂浮、飞行在空中的物体。"
android:textColor="#666"
android:textSize="15sp"/>
</LinearLayout>
</LinearLayout>
2.list_head.xml 头条布局文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/list_head" android:layout_width="match_parent" android:layout_height="match_parent" android:descendantFocusability="blocksDescendants" /> </LinearLayout>3.HeadAdapter.java 头条适配器
package com.example.wjy329.ufo.Adapter; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import com.example.wjy329.ufo.Bean.head; import com.example.wjy329.ufo.R; import com.example.wjy329.ufo.Tools.ImageLoader; import java.util.List; /** * Created by wjy329 on 2017/3/4. */ public class HeadAdapter extends BaseAdapter{ List<head> hl; LayoutInflater inflater; public ImageLoader imageLoader; public HeadAdapter(Context context,List<head> heads){ this.hl = heads; inflater = LayoutInflater.from(context); imageLoader = new ImageLoader(context.getApplicationContext()); } @Override public int getCount() { return hl.size(); } @Override public Object getItem(int position) { return hl.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position,View convertView,ViewGroup parent) { ViewHolder holder; if(convertView ==null){ holder = new ViewHolder(); convertView = inflater.inflate(R.layout.list_item_card_main,null); holder.head_picture = (ImageView) convertView.findViewById(R.id.head_pic); holder.head_title = (TextView) convertView.findViewById(R.id.head_title); holder.head_describe = (TextView) convertView.findViewById(R.id.head_describe); convertView.setTag(holder); }else{ holder = (ViewHolder) convertView.getTag(); } final head head = hl.get(position); imageLoader.DisplayImage(head.getPicture(),holder.head_picture); holder.head_title.setText(head.getTitle()); holder.head_describe.setText(head.getDescribe()); return convertView; } static class ViewHolder { ImageView head_picture; TextView head_title; TextView head_describe; } }上面的ImageLoader是一个加载网络图片的方法。
ImageLoader.java
package com.example.wjy329.ufo.Tools; /** * Created by wjy32 on 2016/3/2. */ import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.widget.ImageView; import com.example.wjy329.ufo.R; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.Collections; import java.util.Map; import java.util.WeakHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ImageLoader { MemoryCache memoryCache=new MemoryCache(); FileCache fileCache; private Map<ImageView, String> imageViews=Collections.synchronizedMap(new WeakHashMap<ImageView, String>()); ExecutorService executorService; public ImageLoader(Context context){ fileCache=new FileCache(context); executorService=Executors.newFixedThreadPool(5); } final int stub_id = R.drawable.mao; public void DisplayImage(String url, ImageView imageView) { imageViews.put(imageView, url); Bitmap bitmap=memoryCache.get(url); if(bitmap!=null) imageView.setImageBitmap(bitmap); else { queuePhoto(url, imageView); imageView.setImageResource(stub_id); } } private void queuePhoto(String url, ImageView imageView) { PhotoToLoad p=new PhotoToLoad(url, imageView); executorService.submit(new PhotosLoader(p)); } private Bitmap getBitmap(String url) { File f=fileCache.getFile(url); //从sd卡 Bitmap b = decodeFile(f); if(b!=null) return b; //从网络 try { Bitmap bitmap=null; URL imageUrl = new URL(url); HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection(); conn.setConnectTimeout(30000); conn.setReadTimeout(30000); conn.setInstanceFollowRedirects(true); InputStream is=conn.getInputStream(); OutputStream os = new FileOutputStream(f); Utils.CopyStream(is, os); os.close(); bitmap = decodeFile(f); return bitmap; } catch (Exception ex){ ex.printStackTrace(); return null; } } //解码图像用来减少内存消耗 private Bitmap decodeFile(File f){ try { //解码图像大小 BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; BitmapFactory.decodeStream(new FileInputStream(f),null,o); //找到正确的刻度值,它应该是2的幂。 final int REQUIRED_SIZE=70; int width_tmp=o.outWidth, height_tmp=o.outHeight; int scale=1; while(true){ if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE) break; width_tmp/=2; height_tmp/=2; scale*=2; } BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize=scale; return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); } catch (FileNotFoundException e) {} return null; } //任务队列 private class PhotoToLoad { public String url; public ImageView imageView; public PhotoToLoad(String u, ImageView i){ url=u; imageView=i; } } class PhotosLoader implements Runnable { PhotoToLoad photoToLoad; PhotosLoader(PhotoToLoad photoToLoad){ this.photoToLoad=photoToLoad; } @Override public void run() { if(imageViewReused(photoToLoad)) return; Bitmap bmp=getBitmap(photoToLoad.url); memoryCache.put(photoToLoad.url, bmp); if(imageViewReused(photoToLoad)) return; BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad); Activity a=(Activity)photoToLoad.imageView.getContext(); a.runOnUiThread(bd); } } boolean imageViewReused(PhotoToLoad photoToLoad){ String tag=imageViews.get(photoToLoad.imageView); if(tag==null || !tag.equals(photoToLoad.url)) return true; return false; } //用于显示位图在UI线程 class BitmapDisplayer implements Runnable { Bitmap bitmap; PhotoToLoad photoToLoad; public BitmapDisplayer(Bitmap b, PhotoToLoad p){bitmap=b;photoToLoad=p;} public void run() { if(imageViewReused(photoToLoad)) return; if(bitmap!=null) photoToLoad.imageView.setImageBitmap(bitmap); else photoToLoad.imageView.setImageResource(stub_id); } } public void clearCache() { memoryCache.clear(); fileCache.clear(); } }FileCache.java
package com.example.wjy329.ufo.Tools; /** * Created by wjy32 on 2016/3/2. */ import android.content.Context; import java.io.File; public class FileCache { private File cacheDir; public FileCache(Context context){ //找一个用来缓存图片的路径 if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"LazyList"); else cacheDir=context.getCacheDir(); if(!cacheDir.exists()) cacheDir.mkdirs(); } public File getFile(String url){ String filename=String.valueOf(url.hashCode()); File f = new File(cacheDir, filename); return f; } public void clear(){ File[] files=cacheDir.listFiles(); if(files==null) return; for(File f:files) f.delete(); } }MemoryCache.java
package com.example.wjy329.ufo.Tools; /** * Created by wjy32 on 2016/3/2. */ import android.graphics.Bitmap; import java.lang.ref.SoftReference; import java.util.Collections; import java.util.HashMap; import java.util.Map; public class MemoryCache { private Map<String, SoftReference<Bitmap>> cache=Collections.synchronizedMap(new HashMap<String, SoftReference<Bitmap>>());//软引用 public Bitmap get(String id){ if(!cache.containsKey(id)) return null; SoftReference<Bitmap> ref=cache.get(id); return ref.get(); } public void put(String id, Bitmap bitmap){ cache.put(id, new SoftReference<Bitmap>(bitmap)); } public void clear() { cache.clear(); } }
4.head.java 头条实体类
package com.example.wjy329.ufo.Bean; import cn.bmob.v3.BmobObject; /** * Created by wjy329 on 2017/3/4. */ public class head extends BmobObject { private String picture; //图片 private String describe; //描述 private String title; //标题 public String getPicture() { return picture; } public void setPicture(String picture) { this.picture = picture; } public String getDescribe() { return describe; } public void setDescribe(String describe) { this.describe = describe; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } }
5.FirstFragment.java 头条主代码
package com.example.wjy329.ufo.fragment; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import com.example.wjy329.ufo.Activity.InfoActivity; import com.example.wjy329.ufo.Adapter.HeadAdapter; import com.example.wjy329.ufo.Bean.head; import com.example.wjy329.ufo.R; import java.util.List; import java.util.Map; import cn.bmob.v3.Bmob; import cn.bmob.v3.BmobQuery; import cn.bmob.v3.exception.BmobException; import cn.bmob.v3.listener.FindListener; import static cn.bmob.v3.Bmob.getApplicationContext; /** * Created by wjy329 on 2017/2/25. */ public class FirstFragment extends Fragment{ ListView listView; HeadAdapter adapter; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.list_head, container, false); //Bmob应用的key Bmob.initialize(this.getActivity(),"618f5d7ccf1b0dc170e0effbfd5dabae"); listView = (ListView) view.findViewById(R.id.list_head); //Bmob查询方法 BmobQuery<head> query =new BmobQuery<head>(); query.order("-createdAt"); query.findObjects(new FindListener<head>() { @Override public void done(List<head> list, BmobException e) { if(e ==null) { adapter = new HeadAdapter(getActivity(), list); listView.setAdapter(adapter); }else{ Log.i("bmob","失败:"+e.getMessage()+","+e.getErrorCode()); Toast.makeText(getApplicationContext(), "网络连接失败,请检查网络", Toast.LENGTH_SHORT).show(); } } }); //item点击事件 listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { head data = (head) listView.getAdapter().getItem(position); Bundle bundle =new Bundle(); bundle.putString("title",data.getTitle()); bundle.putString("content",data.getDescribe()); Intent intent = new Intent(getActivity(), InfoActivity.class); intent.putExtras(bundle); startActivity(intent); } }); return view; } }6.InfoActivity.java 详细信息加载页面,获取intent的传值
package com.example.wjy329.ufo.Activity; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.widget.Toolbar; import android.view.MenuItem; import android.widget.Button; import android.widget.TextView; import com.example.wjy329.ufo.R; import com.example.wjy329.ufo.fragment.FirstFragment; /** * Created by wjy329 on 2017/3/9. */ public class InfoActivity extends Activity { TextView infoTitle_tv; TextView infoContent_tv; Toolbar toolbar; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.info); infoTitle_tv = (TextView) findViewById(R.id.InfoTitle); infoContent_tv = (TextView) findViewById(R.id.InfoContent); toolbar = (Toolbar) findViewById(R.id.toolbar_info); Bundle b = getIntent().getExtras(); String info_title = b.getString("title"); String info_content = b.getString("content"); infoTitle_tv.setText(info_title); infoContent_tv.setText(info_content); toolbar.inflateMenu(R.menu.toolbar_menu_info); toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener(){ @Override public boolean onMenuItemClick(MenuItem item) { int menuItemId = item.getItemId(); if(menuItemId == R.id.action_home){ finish(); } return true; } }); } }
这样就完成了头条的加载,可以从Bmob中更新数据,显示在app上。灵异事件和未解之谜的实现和头条一样,只需稍作修改,这里不再记录。下一篇会记录社区功能的实现。
相关文章推荐
- 基于Bmob的Android资讯类app开发(二)
- Android基于Bmob第三方后台开发的App——足说
- APP 内嵌browser开发HTML5应用(基于android)
- 【基于Jsoup】Android_App暴走笑话开发
- 开发手记——基于XMPP的Android即时通讯APP(二)
- QuickTV:一款基于AndroidQuick快速开发框架实现的直播APP
- android 基于 Retrotfit2.1+Material Design+ijkplayer 开发的一个 APP
- 开发手记——基于XMPP的Android即时通讯APP(一)
- 基于地理位置的Android App-我去 开发技术记录(一:结构)
- 基于Android开发的天气预报app(源码下载)
- 基于微博LBS API开发的周边美图android app
- 开发手记——基于XMPP的Android即时通讯APP(三)
- 滴滴打车,打车软件app实现。小车在地图上平滑移动的实现,Android,基于高德地图开发实现
- ubuntu 14.04/15.10 安装基于eclipse的android app开发环境
- 一款基于 Android 开发的离线版的 MM 图片浏览 App
- AndroidApp开发组件化:基于Nexus和Gradle
- 【Android开发】微信精选,文章资讯类App开发记录总结
- 滴滴打车,打车软件app实现。小车在地图上平滑移动的实现,Android,基于高德地图开发实现