Android仿新浪微博发布微博界面设计(5)
本教程为大家分享了Android发布微博、添加表情等功能的具体代码,供大家参考,具体内容如下
发布一条新微博接口:http://open.weibo.com/wiki/2/statuses/update
上传图片并发布一条新微博接口:http://open.weibo.com/wiki/2/statuses/upload
1.根据有没有图片来选择相应的接口。
2.根据输入框的改变判断文字数。
3.创建一个girlview显示发送的图片,最最多9张,此处由于请求参数的的原因,最多上传一张图片,选择多张图片时,上传最后一张图片。(官方Demo与网络多个Demo均只能上传一张图片。如有看官解决多图上传,请务必联系我!)
4.显示表情的实现:用正则表达式遍历文字内容,代获取与表情相符的内容后, 用SpannableString将对于的表情图片显示在TextView中。
5.表情面板的实现:创建显示表情的GridView,将表情分组放入其中,监听GridView点击事件,将表情显示输入到EditText中。具体表情功能的实现请参考:https://www.jb51.net/article/97862.htm
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(); }
效果图:
上一篇:Dcloud的native.js直接拨打电话Android实例代码
栏 目:Android代码
下一篇:android高仿微信表情输入与键盘输入代码(详细实现分析)
本文地址:http://www.codeinn.net/misctech/35194.html