Android仿新浪微博發(fā)布微博界面設(shè)計(jì)(5)
本教程為大家分享了Android發(fā)布微博、添加表情等功能的具體代碼,供大家參考,具體內(nèi)容如下
發(fā)布一條新微博接口:http://open.weibo.com/wiki/2/statuses/update
上傳圖片并發(fā)布一條新微博接口:http://open.weibo.com/wiki/2/statuses/upload
1.根據(jù)有沒(méi)有圖片來(lái)選擇相應(yīng)的接口。
2.根據(jù)輸入框的改變判斷文字?jǐn)?shù)。
3.創(chuàng)建一個(gè)girlview顯示發(fā)送的圖片,最最多9張,此處由于請(qǐng)求參數(shù)的的原因,最多上傳一張圖片,選擇多張圖片時(shí),上傳最后一張圖片。(官方Demo與網(wǎng)絡(luò)多個(gè)Demo均只能上傳一張圖片。如有看官解決多圖上傳,請(qǐng)務(wù)必聯(lián)系我?。?
4.顯示表情的實(shí)現(xiàn):用正則表達(dá)式遍歷文字內(nèi)容,代獲取與表情相符的內(nèi)容后, 用SpannableString將對(duì)于的表情圖片顯示在TextView中。
5.表情面板的實(shí)現(xiàn):創(chuàng)建顯示表情的GridView,將表情分組放入其中,監(jiān)聽(tīng)GridView點(diǎn)擊事件,將表情顯示輸入到EditText中。具體表情功能的實(shí)現(xiàn)請(qǐng)參考:http://chabaoo.cn/article/97862.htm
5.最終發(fā)送的文字,表情,圖片數(shù)量,根據(jù)按鈕觸發(fā)時(shí)各個(gè)參數(shù)的狀態(tài)而決定。
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; // 發(fā)送圖片的路徑 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); /** * 注冊(cè)輸入框內(nèi)容監(jiān)聽(tīng)器 */ write.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } /** * 當(dāng)輸入框的內(nèi)容變化的時(shí)候執(zhí)行 */ @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); /** * 監(jiān)聽(tīng)GridView點(diǎn)擊事件 */ gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View v, int position, long id) { if (imageItem.size() == 10) { //第一張為默認(rèn)圖片 Toast.makeText(WriteActivity.this, "圖片數(shù)9張已滿", Toast.LENGTH_SHORT).show(); } else if (position == 0) { //點(diǎn)擊圖片位置為+ 0對(duì)應(yīng)0張圖片 //選擇圖片 Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent, 1); //通過(guò)onResume()刷新數(shù)據(jù) } else { dialog(position); } } }); /** * 監(jiān)聽(tīng)發(fā)表按鈕點(diǎn)擊事件 */ tools = Tools.getInstance(); onput.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //對(duì)文字進(jìn)行處理 String mText = write.getText().toString(); int len = mText.length(); if (len == 0) { Toast.makeText(WriteActivity.this, "內(nèi)容不能為空!", Toast.LENGTH_SHORT).show(); } else if (len > 140) { Toast.makeText(WriteActivity.this, "超出字?jǐn)?shù)限制!", Toast.LENGTH_SHORT).show(); } else { if (imagepaths.size() > 0) { tools.postwhitTextandImages(WriteActivity.this, mText,imagepaths); //進(jìn)入微博主界面 Intent intent = new Intent(WriteActivity.this, MainActivity.class); startActivity(intent); WriteActivity.this.finish(); } else { tools.postwhitText(WriteActivity.this, mText); //進(jìn)入微博主界面 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(); } //獲取圖片路徑 響應(yīng)startActivityForResult protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); //打開(kāi)圖片 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); //返回 沒(méi)找到選擇圖片 if (null == cursor) { return; } //光標(biāo)移動(dòng)至開(kāi)頭 獲取圖片路徑 cursor.moveToFirst(); image_path = cursor.getString(cursor .getColumnIndex(MediaStore.Images.Media.DATA)); } } //end if 打開(kāi)圖片 } //刷新圖片 @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); //刷新后釋放防止手機(jī)休眠后自動(dòng)添加 image_path = null; } } /** * Dialog對(duì)話框提示用戶刪除操作 * position為刪除圖片位置 */ protected void dialog(final int position) { AlertDialog.Builder builder = new AlertDialog.Builder(WriteActivity.this); builder.setMessage("確認(rèn)移除已添加圖片嗎?"); builder.setTitle("提示"); builder.setPositiveButton("確認(rèn)", 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(); } /** * 初始化表情面板內(nèi)容 */ 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個(gè)表情作為一組,同時(shí)添加到ViewPager對(duì)應(yīng)的view集合中 if (emotionNames.size() == 20) { GridView gv = createEmotionGridView(emotionNames, gvWidth, spacing, itemWidth, gvHeight); gvs.add(gv); // 添加完一組表情,重新創(chuàng)建一個(gè)表情名字集合 emotionNames = new ArrayList<String>(); } } // 檢查最后是否有不足20個(gè)表情的剩余情況 if (emotionNames.size() > 0) { GridView gv = createEmotionGridView(emotionNames, gvWidth, spacing, itemWidth, gvHeight); gvs.add(gv); } // 將多個(gè)GridView添加顯示到ViewPager中 emotionPagerGvAdapter = new EmotionPagerAdapter(gvs); vp_emotion_dashboard.setAdapter(emotionPagerGvAdapter); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(gvWidth, gvHeight); vp_emotion_dashboard.setLayoutParams(params); } /** * 創(chuàng)建顯示表情的GridView */ private GridView createEmotionGridView(List<String> emotionNames, int gvWidth, int padding, int itemWidth, int gvHeight) { // 創(chuàng)建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設(shè)置表情圖片 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) { // 點(diǎn)擊的是表情 EmotionGvAdapter emotionGvAdapter = (EmotionGvAdapter) itemAdapter; if (position == emotionGvAdapter.getCount() - 1) { // 如果點(diǎn)擊了最后一個(gè)回退按鈕,則調(diào)用刪除鍵事件 write.dispatchKeyEvent(new KeyEvent( KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL)); } else { // 如果點(diǎn)擊了表情,則添加到輸入框中 String emotionName = emotionGvAdapter.getItem(position); // 獲取當(dāng)前光標(biāo)位置,在指定位置上添加表情圖片文本 int curPosition = write.getSelectionStart(); StringBuilder sb = new StringBuilder(write.getText().toString()); sb.insert(curPosition, emotionName); // 特殊文字處理,將表情等轉(zhuǎn)換一下 write.setText(StringUtils.getEmotionContent( this, write, sb.toString())); // 將光標(biāo)設(shè)置到新增完表情的右側(cè) write.setSelection(curPosition + emotionName.length()); } } } }
發(fā)布微博的方法位于Tools.java中。由于上傳的數(shù)據(jù)采用multipart/form-data編碼方式,此處引入第三方httptmime.jar包對(duì)請(qǐng)求參數(shù)進(jìn)行處理。
/** * 發(fā)布一條不含圖片的微博 * * @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, "發(fā)表成功", Toast.LENGTH_SHORT).show(); Looper.loop(); } else { Looper.prepare(); Toast.makeText(context, "發(fā)表失敗", Toast.LENGTH_SHORT).show(); Looper.loop(); } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }.start(); } /** * 發(fā)布一條帶圖片的微博 * * @param context * @param */ public void postwhitTextandImages(final Context context, final String text, final List<String> filesPath) { new Thread() { @Override public void run() { try { //HttpClient對(duì)象 HttpClient httpClient = new DefaultHttpClient(); //采用POST的請(qǐng)求方式 HttpPost httpPost = new HttpPost("https://upload.api.weibo" + ".com/2/statuses/upload.json"); //MultipartEntity對(duì)象,需要httpmime-4.1.1.jar文件。 MultipartEntity multipartEntity = new MultipartEntity(); //StringBody對(duì)象,參數(shù) StringBody param = new StringBody(oAuth.getAccessToken()); multipartEntity.addPart("access_token", param); StringBody param1 = new StringBody(URLEncoder.encode(text)); multipartEntity.addPart("status", param1); //filesPath為L(zhǎng)ist<String>對(duì)象,里面存放的是需要上傳的文件的地址 for (String path : filesPath) { Log.i("------------", path); //FileBody對(duì)象,需要上傳的文件 ContentBody file = new FileBody(new File(path)); multipartEntity.addPart("pic", file); } //將MultipartEntity對(duì)象賦值給HttpPost httpPost.setEntity(multipartEntity); HttpResponse response = null; //執(zhí)行請(qǐng)求,并返回結(jié)果HttpResponse response = httpClient.execute(httpPost); if (response.getStatusLine().getStatusCode() == 200) { Looper.prepare(); Toast.makeText(context, "發(fā)表成功", Toast.LENGTH_SHORT).show(); Looper.loop(); } else { Looper.prepare(); Toast.makeText(context, "發(fā)表失敗", Toast.LENGTH_SHORT).show(); Looper.loop(); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }.start(); }
效果圖:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android仿新浪微博自定義ListView下拉刷新(4)
- Android仿新浪微博分頁(yè)管理界面(3)
- Android仿新浪微博oauth2.0授權(quán)界面實(shí)現(xiàn)代碼(2)
- Android仿新浪微博啟動(dòng)界面或登陸界面(1)
- Android用PopupWindow實(shí)現(xiàn)新浪微博的分組信息實(shí)例
- Android仿新浪微博、QQ空間等帖子顯示(2)
- Android仿新浪微博、QQ空間等帖子顯示(1)
- Android仿新浪微博/QQ空間滑動(dòng)自動(dòng)播放視頻功能
- Android集成新浪微博第三方登錄的方法
- Android仿新浪微博個(gè)人信息界面及其他效果
相關(guān)文章
通知監(jiān)控NotificationListenerService onNotificationPosted重復(fù)回
這篇文章主要為大家介紹了通知監(jiān)控NotificationListenerService onNotificationPosted重復(fù)回調(diào)問(wèn)題解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02Flutter手機(jī)權(quán)限檢查與申請(qǐng)實(shí)現(xiàn)方法詳解
使用flutter進(jìn)行app開(kāi)發(fā),一定會(huì)用到手機(jī)的部分權(quán)限,包括通知推送、定位、相冊(cè)、存儲(chǔ)、相機(jī)、麥克風(fēng)等。而權(quán)限的檢查和獲取,最受歡迎的就是通過(guò)permission_handler這個(gè)插件來(lái)實(shí)現(xiàn)2022-11-11android開(kāi)發(fā)中常用的Eclipse快捷鍵詳細(xì)整理
android開(kāi)發(fā)中常用的Eclipse快捷鍵詳細(xì)整理方便查找,需要的朋友可以了解下2012-12-12Android 數(shù)據(jù)存儲(chǔ)方式有哪幾種
android為數(shù)據(jù)存儲(chǔ)提供了五種方式,有SharedPreferences、文件存儲(chǔ)、SQLite數(shù)據(jù)庫(kù)、ContentProvider、網(wǎng)絡(luò)存儲(chǔ),對(duì)android數(shù)據(jù)存儲(chǔ)方式感興趣的朋友可以通過(guò)本文學(xué)習(xí)一下2015-11-11Android自定義View 實(shí)現(xiàn)鬧鐘喚起播放鬧鐘鈴聲功能
這篇文章主要介紹了Android自定義View 實(shí)現(xiàn)鬧鐘喚起播放鬧鐘鈴聲的效果,本文通過(guò)實(shí)例代碼給大家詳解,需要的朋友可以參考下2016-12-12Android 中使用RecyclerView實(shí)現(xiàn)底部翻頁(yè)
這篇文章主要介紹了Android 中使用RecyclerView實(shí)現(xiàn)底部翻頁(yè)功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-11-11android 設(shè)置圓角圖片實(shí)現(xiàn)代碼
在android應(yīng)用開(kāi)發(fā)中,可能是美化需要,圖片需要處理成圓角,本文將給出實(shí)現(xiàn)代碼,開(kāi)發(fā)中的遇到此問(wèn)題的朋友可以參考下2012-11-11ScrollView與SeekBar綁定實(shí)現(xiàn)滑動(dòng)時(shí)出現(xiàn)小滑塊效果
這篇文章主要為大家詳細(xì)介紹了ScrollView與SeekBar綁定實(shí)現(xiàn)滑動(dòng)時(shí)出現(xiàn)小滑塊效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10