Android仿新浪微博发布微博界面设计(5)
程序员文章站
2024-02-28 21:10:04
本教程为大家分享了android发布微博、添加表情等功能的具体代码,供大家参考,具体内容如下
发布一条新微博接口:
上传图片并发布一条新微博接口:
1.根据有没有图...
本教程为大家分享了android发布微博、添加表情等功能的具体代码,供大家参考,具体内容如下
发布一条新微博接口:
上传图片并发布一条新微博接口:
1.根据有没有图片来选择相应的接口。
2.根据输入框的改变判断文字数。
3.创建一个girlview显示发送的图片,最最多9张,此处由于请求参数的的原因,最多上传一张图片,选择多张图片时,上传最后一张图片。(官方demo与网络多个demo均只能上传一张图片。如有看官解决多图上传,请务必联系我!)
4.显示表情的实现:用正则表达式遍历文字内容,代获取与表情相符的内容后, 用spannablestring将对于的表情图片显示在textview中。
5.表情面板的实现:创建显示表情的gridview,将表情分组放入其中,监听gridview点击事件,将表情显示输入到edittext中。具体表情功能的实现请参考:
5.最终发送的文字,表情,图片数量,根据按钮触发时各个参数的状态而决定。
6.删除选中的图片,获取其位置使用imageitem.remove(position)再将其在arraylist移除。
public class writeactivity extends activity implements adapterview.onitemclicklistener { private button onput, addexpression; private edittext write; private gridview gridview; private textview total_text_num = null; private linearlayout ll_emotion_dashboard; private viewpager vp_emotion_dashboard; // 发送图片的路径 private string image_path; private bitmap bmp; private arraylist<string> imagepaths; private arraylist<hashmap<string, object>> imageitem; private simpleadapter simpleadapter; //适配器 private tools tools; private emotionpageradapter emotionpagergvadapter; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.write); imagepaths = new arraylist<>(); write = (edittext) findviewbyid(r.id.write); total_text_num = (textview) findviewbyid(r.id.total_text_num); onput = (button) findviewbyid(r.id.onput); addexpression = (button) findviewbyid(r.id.addexpression); ll_emotion_dashboard = (linearlayout) findviewbyid(r.id.ll_emotion_dashboard); vp_emotion_dashboard = (viewpager) findviewbyid(r.id.vp_emotion_dashboard); /** * 注册输入框内容监听器 */ write.addtextchangedlistener(new textwatcher() { @override public void beforetextchanged(charsequence s, int start, int count, int after) { } /** * 当输入框的内容变化的时候执行 */ @override public void ontextchanged(charsequence s, int start, int before, int count) { boolean flag = false; string mtext = write.gettext().tostring(); int len = mtext.length(); if (len > 140) { total_text_num.settextcolor(color.red); } else { total_text_num.settextcolor(color.green); } total_text_num.settext(string.valueof(140 - len)); } @override public void aftertextchanged(editable s) { } }); gridview = (gridview) findviewbyid(r.id.images); bmp = bitmapfactory.decoderesource(getresources(), r.drawable.add); imageitem = new arraylist<hashmap<string, object>>(); hashmap<string, object> map = new hashmap<string, object>(); map.put("itemimage", bmp); imageitem.add(map); simpleadapter = new simpleadapter(this, imageitem, r.layout.griditem_addpic, new string[]{"itemimage"}, new int[]{r.id.imageview}); simpleadapter.setviewbinder(new simpleadapter.viewbinder() { @override public boolean setviewvalue(view view, object data, string textrepresentation) { if (view instanceof imageview && data instanceof bitmap) { imageview i = (imageview) view; i.setimagebitmap((bitmap) data); return true; } return false; } }); gridview.setadapter(simpleadapter); /** * 监听gridview点击事件 */ gridview.setonitemclicklistener(new adapterview.onitemclicklistener() { @override public void onitemclick(adapterview<?> parent, view v, int position, long id) { if (imageitem.size() == 10) { //第一张为默认图片 toast.maketext(writeactivity.this, "图片数9张已满", toast.length_short).show(); } else if (position == 0) { //点击图片位置为+ 0对应0张图片 //选择图片 intent intent = new intent(intent.action_pick, android.provider.mediastore.images.media.external_content_uri); startactivityforresult(intent, 1); //通过onresume()刷新数据 } else { dialog(position); } } }); /** * 监听发表按钮点击事件 */ tools = tools.getinstance(); onput.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { //对文字进行处理 string mtext = write.gettext().tostring(); int len = mtext.length(); if (len == 0) { toast.maketext(writeactivity.this, "内容不能为空!", toast.length_short).show(); } else if (len > 140) { toast.maketext(writeactivity.this, "超出字数限制!", toast.length_short).show(); } else { if (imagepaths.size() > 0) { tools.postwhittextandimages(writeactivity.this, mtext,imagepaths); //进入微博主界面 intent intent = new intent(writeactivity.this, mainactivity.class); startactivity(intent); writeactivity.this.finish(); } else { tools.postwhittext(writeactivity.this, mtext); //进入微博主界面 intent intent = new intent(writeactivity.this, mainactivity.class); startactivity(intent); writeactivity.this.finish(); } } } }); /** * 表情按钮及功能 */ addexpression.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { // 隐藏或显示表情面板 ll_emotion_dashboard.setvisibility( ll_emotion_dashboard.getvisibility() == view.visible ? view.gone : view.visible); } }); initemotion(); } //获取图片路径 响应startactivityforresult protected void onactivityresult(int requestcode, int resultcode, intent data) { super.onactivityresult(requestcode, resultcode, data); //打开图片 if (resultcode == result_ok && requestcode == 1) { uri uri = data.getdata(); if (!textutils.isempty(uri.getauthority())) { //查询选择图片 cursor cursor = getcontentresolver().query( uri, new string[]{mediastore.images.media.data}, null, null, null); //返回 没找到选择图片 if (null == cursor) { return; } //光标移动至开头 获取图片路径 cursor.movetofirst(); image_path = cursor.getstring(cursor .getcolumnindex(mediastore.images.media.data)); } } //end if 打开图片 } //刷新图片 @override protected void onresume() { super.onresume(); if (!textutils.isempty(image_path)) { bitmap addbmp = bitmapfactory.decodefile(image_path); hashmap<string, object> map = new hashmap<string, object>(); map.put("itemimage", addbmp); imageitem.add(map); simpleadapter = new simpleadapter(this, imageitem, r.layout.griditem_addpic, new string[]{"itemimage"}, new int[]{r.id.imageview}); simpleadapter.setviewbinder(new simpleadapter.viewbinder() { @override public boolean setviewvalue(view view, object data, string textrepresentation) { if (view instanceof imageview && data instanceof bitmap) { imageview i = (imageview) view; i.setimagebitmap((bitmap) data); return true; } return false; } }); gridview.setadapter(simpleadapter); simpleadapter.notifydatasetchanged(); imagepaths.add(image_path); //刷新后释放防止手机休眠后自动添加 image_path = null; } } /** * dialog对话框提示用户删除操作 * position为删除图片位置 */ protected void dialog(final int position) { alertdialog.builder builder = new alertdialog.builder(writeactivity.this); builder.setmessage("确认移除已添加图片吗?"); builder.settitle("提示"); builder.setpositivebutton("确认", new dialoginterface.onclicklistener() { @override public void onclick(dialoginterface dialog, int which) { dialog.dismiss(); imageitem.remove(position); imagepaths.remove(position - 1); simpleadapter.notifydatasetchanged(); } }); builder.setnegativebutton("取消", new dialoginterface.onclicklistener() { @override public void onclick(dialoginterface dialog, int which) { dialog.dismiss(); } }); builder.create().show(); } /** * 初始化表情面板内容 */ private void initemotion() { // 获取屏幕宽度 int gvwidth = displayutils.getscreenwidthpixels(this); // 表情边距 int spacing = displayutils.dp2px(this, 8); // gridview中item的宽度 int itemwidth = (gvwidth - spacing * 8) / 7; int gvheight = itemwidth * 3 + spacing * 4; list<gridview> gvs = new arraylist<gridview>(); list<string> emotionnames = new arraylist<string>(); // 遍历所有的表情名字 for (string emojiname : emotionutils.emojimap.keyset()) { emotionnames.add(emojiname); // 每20个表情作为一组,同时添加到viewpager对应的view集合中 if (emotionnames.size() == 20) { gridview gv = createemotiongridview(emotionnames, gvwidth, spacing, itemwidth, gvheight); gvs.add(gv); // 添加完一组表情,重新创建一个表情名字集合 emotionnames = new arraylist<string>(); } } // 检查最后是否有不足20个表情的剩余情况 if (emotionnames.size() > 0) { gridview gv = createemotiongridview(emotionnames, gvwidth, spacing, itemwidth, gvheight); gvs.add(gv); } // 将多个gridview添加显示到viewpager中 emotionpagergvadapter = new emotionpageradapter(gvs); vp_emotion_dashboard.setadapter(emotionpagergvadapter); linearlayout.layoutparams params = new linearlayout.layoutparams(gvwidth, gvheight); vp_emotion_dashboard.setlayoutparams(params); } /** * 创建显示表情的gridview */ private gridview createemotiongridview(list<string> emotionnames, int gvwidth, int padding, int itemwidth, int gvheight) { // 创建gridview gridview gv = new gridview(this); gv.setbackgroundcolor(color.rgb(233, 233, 233)); gv.setselector(android.r.color.transparent); gv.setnumcolumns(7); gv.setpadding(padding, padding, padding, padding); gv.sethorizontalspacing(padding); gv.setverticalspacing(padding); layoutparams params = new layoutparams(gvwidth, gvheight); gv.setlayoutparams(params); // 给gridview设置表情图片 emotiongvadapter adapter = new emotiongvadapter(this, emotionnames, itemwidth); gv.setadapter(adapter); gv.setonitemclicklistener(this); return gv; } @override public void onitemclick(adapterview<?> parent, view view, int position, long id) { object itemadapter = parent.getadapter(); if (itemadapter instanceof emotiongvadapter) { // 点击的是表情 emotiongvadapter emotiongvadapter = (emotiongvadapter) itemadapter; if (position == emotiongvadapter.getcount() - 1) { // 如果点击了最后一个回退按钮,则调用删除键事件 write.dispatchkeyevent(new keyevent( keyevent.action_down, keyevent.keycode_del)); } else { // 如果点击了表情,则添加到输入框中 string emotionname = emotiongvadapter.getitem(position); // 获取当前光标位置,在指定位置上添加表情图片文本 int curposition = write.getselectionstart(); stringbuilder sb = new stringbuilder(write.gettext().tostring()); sb.insert(curposition, emotionname); // 特殊文字处理,将表情等转换一下 write.settext(stringutils.getemotioncontent( this, write, sb.tostring())); // 将光标设置到新增完表情的右侧 write.setselection(curposition + emotionname.length()); } } } }
发布微博的方法位于tools.java中。由于上传的数据采用multipart/form-data编码方式,此处引入第三方httptmime.jar包对请求参数进行处理。
/** * 发布一条不含图片的微博 * * @param context * @param text */ public void postwhittext(final context context, final string text) { if (oauth == null) { oauth = oauth.getoauth(context); } new thread() { @override public void run() { try { httppost post = new httppost("https://api.weibo.com/2/statuses/update" + ".json"); list<namevaluepair> params = new arraylist<namevaluepair>(); params.add(new basicnamevaluepair("access_token", oauth.getaccesstoken())); params.add(new basicnamevaluepair("status", text)); post.setentity(new urlencodedformentity(params, http.utf_8)); httpresponse response = httpclient.execute(post); if (response.getstatusline().getstatuscode() == 200) { looper.prepare(); toast.maketext(context, "发表成功", toast.length_short).show(); looper.loop(); } else { looper.prepare(); toast.maketext(context, "发表失败", toast.length_short).show(); looper.loop(); } } catch (unsupportedencodingexception e) { e.printstacktrace(); } catch (clientprotocolexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); } } }.start(); } /** * 发布一条带图片的微博 * * @param context * @param */ public void postwhittextandimages(final context context, final string text, final list<string> filespath) { new thread() { @override public void run() { try { //httpclient对象 httpclient httpclient = new defaulthttpclient(); //采用post的请求方式 httppost httppost = new httppost("https://upload.api.weibo" + ".com/2/statuses/upload.json"); //multipartentity对象,需要httpmime-4.1.1.jar文件。 multipartentity multipartentity = new multipartentity(); //stringbody对象,参数 stringbody param = new stringbody(oauth.getaccesstoken()); multipartentity.addpart("access_token", param); stringbody param1 = new stringbody(urlencoder.encode(text)); multipartentity.addpart("status", param1); //filespath为list<string>对象,里面存放的是需要上传的文件的地址 for (string path : filespath) { log.i("------------", path); //filebody对象,需要上传的文件 contentbody file = new filebody(new file(path)); multipartentity.addpart("pic", file); } //将multipartentity对象赋值给httppost httppost.setentity(multipartentity); httpresponse response = null; //执行请求,并返回结果httpresponse response = httpclient.execute(httppost); if (response.getstatusline().getstatuscode() == 200) { looper.prepare(); toast.maketext(context, "发表成功", toast.length_short).show(); looper.loop(); } else { looper.prepare(); toast.maketext(context, "发表失败", toast.length_short).show(); looper.loop(); } } catch (clientprotocolexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); } } }.start(); }
效果图:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。