Android腾讯微博客户端开发四:微博发送篇(QQ表情,@搜索)

凌晨发帖不容易啊, :cry: 有一个问题,谁做过android的自定义表情啊?貌似还没有发现有客户端有,都是图片,如果能像在电脑上那样自定义表情的功能多好,那位大哥知道,麻烦告知一声,呵呵。写完,睡觉。
[img]http://dl.iteye.com/upload/attachment/524071/8b6e17de-aa55-3593-bffb-cb4216f55be5.jpg[/img]
我们仔细来观察下腾讯微博的qq表情发送规律,由/开始,1到3个中文或者英文字符.
[img]http://dl.iteye.com/upload/attachment/524073/7c935966-5fff-3a1e-9629-d770c68e188c.jpg[/img]
写个工具类来测试已测试正则表达式来匹配表情。
[img]http://dl.iteye.com/upload/attachment/524075/15e28962-cb75-33df-b7c8-60c79deaa240.jpg[/img]

[img]http://dl.iteye.com/upload/attachment/524077/644a3fe6-1526-37ed-aefd-671c50b1e172.jpg[/img]
在上方输入框中可以输入查询 格式为 @你选择的列表值
[img]http://dl.iteye.com/upload/attachment/524079/6d3ff6b6-0ea4-32c7-ae0b-0fdc2a629ab9.jpg[/img]
这个是话题输入界面,格式为#话题#
[img]http://dl.iteye.com/upload/attachment/524081/617b2f26-c5d5-3786-9cef-d26312ba3fae.jpg[/img]
表情选择页面,这个其实是一个每行5列的GridView

[img]http://dl.iteye.com/upload/attachment/524083/0943f699-0861-3544-9566-1b570fea0da3.jpg[/img]
此界面可看到你写的微博的内容,点击发送,发送成功
[img]http://dl.iteye.com/upload/attachment/524085/c2d622d5-86e8-3f48-b49f-be678e651926.jpg[/img]
哈哈,看到了吧,我的微博首页已经显示了我刚才发送的带有话题@person和表情的微博了。

[color=red]接下来,上代码。[/color]
public class AddWeiboActivity extends Activity implements OnClickListener{

private DataHelper dataHelper;
private UserInfo user;
private String user_default_name;
private MyWeiboSync weibo;
private ListView listView;
private EditText weibo_content;
private Button send_btn;
private Button add_cmamera_btn;
private Button add_at_btn;
private Button add_topic_btn;
private Button add_expression_btn;
private Button add_location_btn;
private GridView expressionGrid;
private List<Map<String,Object>> expressionList;
private ExpressionAdapter expressionAdapter;
private FrameLayout operation_layout;
private RelativeLayout add_top_bar;

private ListView atListView;
private RelativeLayout atRootLayout;
private EditText atEditText;
private Button atEnterBtn;
private TextView topic_tip;

private RelativeLayout.LayoutParams atEdiLayoutParams,atEnterBtnLayoutParams,atListViewLayoutParams,topicTipViewLayoutParams;

private JSONArray array;
private Handler handler;
private ArrayAdapter atAdapter;
private List<String> atList;
private AtThread thread;
private List<String> matchStrList;//选择atList匹配的字符串
private int flag;
private static int FLAG_1 = 1;
private static int FLAG_2 = 2;//1和2代表atEnterBtn的父亲控件不同

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_weibo);

setUpViews();
setUpListeners();

dataHelper = DataBaseContext.getInstance(getApplicationContext());
weibo = WeiboContext.getInstance();

SharedPreferences preferences = getSharedPreferences("default_user",Activity.MODE_PRIVATE);
user_default_name = preferences.getString("user_default_name", "");//取得微博默认登录账号信息

handler = new AtHandler();
thread = new AtThread();
thread.start();//开启一个线程获取数据
}

private void setUpViews(){
weibo_content = (EditText)findViewById(R.id.weibo_content);
send_btn = (Button)findViewById(R.id.send_btn);
add_cmamera_btn = (Button)findViewById(R.id.add_cmamera_btn);
add_at_btn = (Button)findViewById(R.id.add_at_btn);
add_topic_btn = (Button)findViewById(R.id.add_topic_btn);
add_expression_btn = (Button)findViewById(R.id.add_expression_btn);
add_location_btn = (Button)findViewById(R.id.add_location_btn);

add_top_bar = (RelativeLayout)findViewById(R.id.add_top_bar);
operation_layout = (FrameLayout)findViewById(R.id.operation_layout);
expressionGrid = new GridView(this);
expressionGrid.setNumColumns(5);
expressionList = buildExpressionsList();
expressionAdapter = new ExpressionAdapter(AddWeiboActivity.this, expressionList);
expressionGrid.setAdapter(expressionAdapter);

//以下代码至本方法setUpViews结束,是个人纯粹蛋疼联系纯代码布局,各位老大可以改成xml布局,淡定

atRootLayout = new RelativeLayout(AddWeiboActivity.this);

atEditText = new EditText(AddWeiboActivity.this);
atEditText.setId(10000);

atEnterBtn = new Button(AddWeiboActivity.this);
atEnterBtn.setBackgroundDrawable(getResources().getDrawable(R.drawable.btn_enter_selector));

atListView = new ListView(AddWeiboActivity.this);
atListView.setCacheColorHint(Color.TRANSPARENT);//防止滑屏时出现黑快,不信可以注释掉此句试一试
atListView.setDivider(getResources().getDrawable(R.drawable.list_divider));//设置分割线
atListView.setBackgroundColor(Color.argb(255, 239, 239, 239));//alpha通道一定不要设置成透明的了,要不然textView什么也看不见,因为这个我找了很久,以为代码错了,最后才发现是透明的

topic_tip = new TextView(AddWeiboActivity.this);
topic_tip.setText("请输入话题");
topic_tip.setTextSize(20);
topic_tip.setTextColor(Color.argb(255, 90, 142, 189));//alpha通道一定不要设置成透明的了,要不然textView什么也看不见,因为这个我找了很久,以为代码错了,最后才发现是透明的

atRootLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
atEdiLayoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,80);
atEnterBtnLayoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
atListViewLayoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);
topicTipViewLayoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);


//添加布局约束
atEdiLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);

atEnterBtnLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP,RelativeLayout.TRUE);
atEnterBtnLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,RelativeLayout.TRUE);
atEnterBtnLayoutParams.setMargins(0, 10, 10, 0);//设置边距,分别代表左,上,右,下

atListViewLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM,RelativeLayout.TRUE);
atListViewLayoutParams.addRule(RelativeLayout.BELOW, atEditText.getId());

topicTipViewLayoutParams.addRule(RelativeLayout.BELOW, atEditText.getId());

}

private void setUpListeners(){
send_btn.setOnClickListener(this);
add_cmamera_btn.setOnClickListener(this);
add_at_btn.setOnClickListener(this);
add_topic_btn.setOnClickListener(this);
add_expression_btn.setOnClickListener(this);
add_location_btn.setOnClickListener(this);
expressionGrid.setOnItemClickListener(new GridItemClickListener());
atListView.setOnItemClickListener(new AtListViewItemListener());
atEditText.addTextChangedListener(new MyTextWatcher());
atEnterBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
add_top_bar.setVisibility(View.VISIBLE);
weibo_content.setVisibility(View.VISIBLE);
operation_layout.setVisibility(View.GONE);
operation_layout.removeAllViews();//别忘记要移除掉
if(flag==FLAG_1){
weibo_content.setText(weibo_content.getText()+"@");
}else if(flag==FLAG_2){
weibo_content.setText(weibo_content.getText()+"#"+atEditText.getText()+"#");
}


}
});
}

class AtThread extends Thread {
@Override
public void run() {
String jsonStr = weibo.getFans(weibo.getAccessTokenKey(), weibo.getAccessTokenSecrect(), 20, 0, user_default_name);
try {
JSONObject dataObj = new JSONObject(jsonStr).getJSONObject("data");
array = dataObj.getJSONArray("info");
} catch (JSONException e) {
e.printStackTrace();
}
//通知handler处理数据
Message msg = handler.obtainMessage();
handler.sendMessage(msg);
}
}

class AtHandler extends Handler {
@Override
public void handleMessage(Message msg){
int size = array.length();
atList = new ArrayList<String>();
for(int i = 0;i<size;i++){
JSONObject data = array.optJSONObject(i);
try {
atList.add(data.getString("nick")+"("+data.getString("name")+")");
} catch (JSONException e) {
e.printStackTrace();
}
}
matchStrList = new ArrayList<String>();
matchStrList.addAll(atList);
atAdapter = new ArrayAdapter<String>(AddWeiboActivity.this,R.layout.at_list_item,R.id.at_nick_name,atList);
atListView.setAdapter(atAdapter);
}
}

class ExpressionAdapter extends BaseAdapter {
private Context context;
private LayoutInflater inflater;
private List<Map<String,Object>> list;

public ExpressionAdapter(Context context, List<Map<String,Object>> list) {
super();
this.context = context;
this.list = list;
this.inflater = LayoutInflater.from(context);
}

@Override
public int getCount() {
return list.size();
}

@Override
public Object getItem(int position) {
return list.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent){
Map<String,Object> map = list.get(position);
ImageView image = new ImageView(context);
image.setImageDrawable((Drawable)map.get("drawable"));
return image;
}
}

@Override
public void onClick(View v) {
if(operation_layout.getChildCount()>0){
add_top_bar.setVisibility(View.VISIBLE);
weibo_content.setVisibility(View.VISIBLE);
operation_layout.setVisibility(View.GONE);
operation_layout.removeAllViews();//别忘记要移除掉
return;
}
switch (v.getId()) {

case R.id.send_btn:{
String returnStr = weibo.publishMsg(weibo.getAccessTokenKey(), weibo.getAccessTokenSecrect(), weibo_content.getText().toString());
try {
JSONObject dataObj = new JSONObject(returnStr);
if("ok".equals(dataObj.getString("msg"))){
Toast.makeText(AddWeiboActivity.this, "发送成功", Toast.LENGTH_SHORT).show();//我日,记得要show,每次都搞忘记
}
} catch (JSONException e) {
e.printStackTrace();
}
}
break;
case R.id.add_cmamera_btn:{

}
break;
case R.id.add_at_btn:{
// 动态的组装view
atRootLayout.removeAllViews();// 组装前先把所有的孩子拿掉
atEditText.setText("@");
flag = FLAG_1;//区分atEnterBtn是在哪个界面按的
atRootLayout.addView(atEditText, atEdiLayoutParams);
atRootLayout.addView(atEnterBtn, atEnterBtnLayoutParams);
atRootLayout.addView(atListView, atListViewLayoutParams);
operation_layout.addView(atRootLayout);

add_top_bar.setVisibility(View.GONE);// 隐藏上面的bar和文本编辑框,不让之与at选择相互影响
weibo_content.setVisibility(View.GONE);
operation_layout.setVisibility(View.VISIBLE);
}
break;
case R.id.add_topic_btn:{
//动态的组装view
atRootLayout.removeAllViews();//组装前先把所有的孩子拿掉
atEditText.setText("");
flag = FLAG_2;//区分atEnterBtn是在哪个界面按的
atRootLayout.addView(atEditText,atEdiLayoutParams);
atRootLayout.addView(atEnterBtn,atEnterBtnLayoutParams);
atRootLayout.addView(topic_tip,topicTipViewLayoutParams);
operation_layout.addView(atRootLayout);

add_top_bar.setVisibility(View.GONE);// 隐藏上面的bar和文本编辑框,不让之与at选择相互影响
weibo_content.setVisibility(View.GONE);
operation_layout.setVisibility(View.VISIBLE);
}
break;
case R.id.add_expression_btn:{
add_top_bar.setVisibility(View.GONE);//隐藏上面的bar和文本编辑框,不让之与表情选择的gridView相互影响
weibo_content.setVisibility(View.GONE);
operation_layout.addView(expressionGrid);
operation_layout.setVisibility(View.VISIBLE);
}
break;
case R.id.add_location_btn:{

}
break;
default:
break;
}
}
private List<Map<String,Object>> buildExpressionsList(){
List<Map<String,Object>> list = new ArrayList<Map<String, Object>>();
DecimalFormat df = new DecimalFormat("000");//格式化数字
for(int i = 0;i<105;i++){
Map<String,Object> map = new HashMap<String, Object>();
String formatStr = "h"+df.format(i);
int drawableId = 0 ;
try {
drawableId = R.drawable.class.getDeclaredField(formatStr).getInt(this);//反射取得id,这个地方循环套反射,是不是很耗性能啊,我没测试过,麻烦有好办法的兄弟姐妹分享一下
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
Drawable drawable = getResources().getDrawable(drawableId);
map.put("drawableId", formatStr);
map.put("drawable",drawable);
list.add(map);
}
return list;
}

class GridItemClickListener implements OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position,long arg3) {
Map<String, Object> map = expressionList.get(position);
String drawableId = (String)map.get("drawableId");

add_top_bar.setVisibility(View.VISIBLE);
weibo_content.setVisibility(View.VISIBLE);
operation_layout.setVisibility(View.GONE);
operation_layout.removeAllViews();//别忘记要移除掉

String expressionStr=null;
expressionStr = TextUtil.drawableIdToFaceName.get(drawableId);
expressionStr="/"+expressionStr;
weibo_content.setText(weibo_content.getText().toString()+expressionStr);
}
}

class MyTextWatcher implements TextWatcher{
@Override
public void afterTextChanged(Editable s){
String changingStr = atEditText.getText().toString();
if(changingStr.indexOf("@")!=-1){
changingStr = changingStr.substring(1);
}

int size = atList.size();
matchStrList.clear();
for(int i = 0;i<size;i++){
String currentStr = atList.get(i);
if(currentStr.indexOf(changingStr)!=-1){
matchStrList.add(currentStr);
}
}
atAdapter = new ArrayAdapter<String>(AddWeiboActivity.this,R.layout.at_list_item,R.id.at_nick_name,matchStrList);
atAdapter.notifyDataSetChanged();
atListView.setAdapter(atAdapter);
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {

}

@Override
public void onTextChanged(CharSequence s, int start, int before,int count) {

}
}

class AtListViewItemListener implements OnItemClickListener{
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,long arg3){
add_top_bar.setVisibility(View.VISIBLE);
weibo_content.setVisibility(View.VISIBLE);
operation_layout.setVisibility(View.GONE);
operation_layout.removeAllViews();//别忘记要移除掉

String str = matchStrList.get(position);
String nickStr = str.substring(0,str.indexOf("("));
weibo_content.setText(weibo_content.getText()+"@"+nickStr);
}
}
}


add_weibo.xml:
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffffff" xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout android:id="@+id/add_top_bar" android:background="@drawable/header" android:layout_width="fill_parent" android:layout_height="wrap_content">
<Button android:text="发送" android:id="@+id/send_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5.0dip" android:layout_alignParentRight="true"/>
<TextView android:text="写广播" android:textSize="16.0sp" android:textColor="#ffffffff" android:ellipsize="middle" android:gravity="center_horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" android:layout_alignParentLeft="true" android:layout_marginLeft="10.0dip" android:layout_centerVertical="true"/>
</RelativeLayout>
<EditText android:id="@+id/weibo_content" android:gravity="top" android:layout_below="@id/add_top_bar" android:background="@null" android:textColor="@null" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="fill_parent"/>
<RelativeLayout android:id="@+id/add_bottom_bar" android:background="@drawable/header" android:layout_width="fill_parent" android:layout_height="50.0dip" android:layout_alignParentBottom="true" android:layout_marginTop="5.0dip">
<Button android:id="@+id/add_cmamera_btn" android:background="@drawable/add_pic_selector" android:focusable="false" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="8.0dip" android:layout_marginRight="12.0dip" android:layout_alignParentLeft="true" android:layout_centerVertical="true" />
<Button android:id="@+id/add_at_btn" android:background="@drawable/add_at_selector" android:focusable="false" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="12.0dip" android:layout_toRightOf="@id/add_cmamera_btn" android:layout_centerVertical="true" />
<Button android:id="@+id/add_topic_btn" android:background="@drawable/add_topic_selector" android:focusable="false" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="12.0dip" android:layout_toRightOf="@id/add_at_btn" android:layout_centerVertical="true" />
<Button android:id="@+id/add_expression_btn" android:background="@drawable/add_emo_selector" android:focusable="false" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="12.0dip" android:layout_toRightOf="@id/add_topic_btn" android:layout_centerVertical="true" />
<Button android:id="@+id/add_location_btn" android:background="@drawable/add_location_selector" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/add_expression_btn" android:layout_centerVertical="true" />
<TextView android:textSize="12.0sp" android:text="140" android:textColor="#c6cbce" android:id="@+id/remain_count" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="12.0dip" android:layout_alignParentRight="true" android:layout_centerVertical="true" />
</RelativeLayout>
<FrameLayout android:layout_gravity="bottom" android:id="@+id/operation_layout" android:background="@android:color/transparent" android:paddingBottom="50.0dip" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="fill_parent" />
</RelativeLayout>

表情解析先关 :下图是drawable文件下的表情文件
[img]http://dl.iteye.com/upload/attachment/524087/dc5b213d-bec9-3432-8749-16f6b3035398.jpg[/img]

static{//表情文件和表情id的对应的HashMap<String,String>
drawableIdToFaceName.put("h000","调皮");
drawableIdToFaceName.put("h001","呲牙");
drawableIdToFaceName.put("h002","惊讶");
drawableIdToFaceName.put("h003","难过");
drawableIdToFaceName.put("h004","酷");
drawableIdToFaceName.put("h005","冷汗");
drawableIdToFaceName.put("h006","抓狂");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值