聊天界面的制作(三)——表情列表发送功能

基本功能

1. 自定义标题栏。(标题栏不做任何功能)

2. 有左右发送按钮。(这个只能自己和自己聊天哦,所以有左右发送按钮)

  (1)点击左边按钮发送按钮,在ListView的左侧显示。
  (2)点击右边按钮发送按钮,在ListView的右侧显示。
  
3.有表情发送按钮。

  (1)当点击表情发送按钮时, 弹出表情框,点击想要发送的表情将其添加输入框中。
  (2)当在此点击表情按钮时,表情框收回。
  (3)当表情框处在显示状态时, 点击输入框时,表情框收回。

聊天界面的制作(一)——基本布局的实现
聊天界面的制作(二)——发送消息后ListView左右布局显示
源码下载链接

表情列表发送功能

1. 在总布局中添加一个GridView控件,用于显示表情列表。控件中设置一个android:visibility="gone"让其不显示且不占用空间。当点击表情按钮时才显示,也就是将其值在设置为”visible”;当在次点击时,不显示表情框,也就是又将其值设置为”gone”。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <include
        android:id="@+id/title_bar"
        layout="@layout/title_bar"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="@drawable/chatting_background"
        android:listSelector="@android:color/transparent">ListView>

    <LinearLayout
        android:id="@+id/linearlayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/grey"
        android:gravity="bottom"
        android:orientation="horizontal">

        <ImageButton
            android:id="@+id/imagebutton_expression"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_margin="10dp"
            android:focusable="true"
            android:background="@drawable/imagebutton_expression" />

        <Button
            android:id="@+id/button_left"
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:layout_margin="5dp"
            android:background="@drawable/button_send_background"
            android:padding="5dp"
            android:text="发送"
            android:textColor="@color/white" />

        <EditText
            android:id="@+id/edittext_input"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:layout_weight="1"
            android:background="@drawable/edittext_background"
            android:padding="7dp"
            android:layout_gravity="center"/>

        <Button
            android:id="@+id/button_right"
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:layout_margin="5dp"
            android:background="@drawable/button_send_background"
            android:padding="5dp"
            android:text="发送"
            android:textColor="@color/white" />
    LinearLayout>
    <GridView
        android:id="@+id/gridview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:numColumns="7"
        android:visibility="visible"
        android:background="@color/grey">

    GridView>

LinearLayout>

2. 首先定义一个布局,用于在GridView中的Item中显示每一个表情。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/imageview_expression"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:src="@mipmap/dra" />

LinearLayout>

定义ExpressionAdapter将表情数据添加到布局中。

public class ExpressionAdapter extends BaseAdapter {

    //表情数据
    private int[] mExpression = {R.mipmap.dra,R.mipmap.drb,R.mipmap.drc,R.mipmap.drd,R.mipmap.dre,R.mipmap.drf,R.mipmap.drg,
            R.mipmap.drh,R.mipmap.dri,R.mipmap.drj,R.mipmap.drk,R.mipmap.drl,R.mipmap.drm,R.mipmap.drn,
            R.mipmap.dro,R.mipmap.drp,R.mipmap.drq,R.mipmap.drr,R.mipmap.drs,R.mipmap.drt,R.mipmap.dru,
            R.mipmap.drv,R.mipmap.drw,R.mipmap.drx,R.mipmap.dry,R.mipmap.drz,R.mipmap.dra};

    private LayoutInflater mInflater;

    public ExpressionAdapter(LayoutInflater mInflater) {
        this.mInflater = mInflater;
    }

    @Override
    public int getCount() {
        return mExpression.length;
    }

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup viewGroup) {

        ViewHolder viewHolder = null;
        if(convertView == null){
            convertView = mInflater.inflate(R.layout.item_expression, null);
            viewHolder = new ViewHolder();
            viewHolder.imageview = (ImageView) convertView.findViewById(R.id.imageview_expression);
            convertView.setTag(viewHolder);
        }else {
            viewHolder = (ViewHolder) convertView.getTag();

        }
        viewHolder.imageview.setImageResource(mExpression[position]);
        return convertView;
    }
    class ViewHolder{
        ImageView imageview;
    }
}

3. 定义一个富文本,富文本中需要创建ImageGetter对象。然后通过Spanned对象ImageGetter对象返回的id来获得图片。

public class MainActivity extends Activity implements View.OnClickListener {

    private Button mButtonLeft;//左边发送按钮
    private Button mButtonRight;//右边发送按钮
    private EditText mEditTextInput;//输入框
    private ListView mListView;//显示消息的ListView
    private GridView mGridView;//显示表情的GridView
    private ImageButton mImageButtonExpression;//弹出和收回表情框的按钮
    private Spanned mSpanned;//富文本
    private Html.ImageGetter mImageGetter;//获得富文本图片
    private List mData;//消息数据
    private MessageAdapter mMessageAdapter;//消息适配器
    private ExpressionAdapter mExpressionAdapter;//表情适配器
    private InputMethodManager mInputMethodManager;//用于控制手机键盘的显示有否的对象(此处)
    //表情数据名称
    private String[] mExpression = {"dra", "drb", "drc", "drd", "dre", "drf",
            "drg", "drh", "dri", "drg", "drk", "drl",
            "drm", "drn", "dro", "drp", "drq", "drr",
            "drs", "drt", "dru", "drv", "drw", "drx",
            "dry", "drz", "dra"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mButtonLeft = (Button) findViewById(R.id.button_left);
        mButtonRight = (Button) findViewById(R.id.button_right);
        mEditTextInput = (EditText) findViewById(R.id.edittext_input);
        mImageButtonExpression = (ImageButton) findViewById(R.id.imagebutton_expression);
        mListView = (ListView) findViewById(R.id.listview);
        mGridView = (GridView) findViewById(R.id.gridview);
        mButtonLeft.setOnClickListener(this);
        mButtonRight.setOnClickListener(this);
        mImageButtonExpression.setOnClickListener(this);
        mInputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
        //消息数据初始化
        mData = new ArrayList();
        //通过反射获得图片的id
        mImageGetter = new Html.ImageGetter() {
            @Override
            public Drawable getDrawable(String s) {
                Drawable drawable = null;
                int id = R.mipmap.dra;
                if (s != null) {
                    Class clazz = R.mipmap.class;
                    try {
                        Field field = clazz.getDeclaredField(s);
                        id = field.getInt(s);

                    } catch (NoSuchFieldException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }

                }
                drawable = getResources().getDrawable(id);
                drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
                return drawable;
            }
        };
        mExpressionAdapter = new ExpressionAdapter(getLayoutInflater());
        mGridView.setAdapter(mExpressionAdapter);
        //点击表情,将表情添加到输入框中。
        mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView adapterView, View view, int position, long l) {
                //通过mImageGetter获得id获得表情图片,然后将其添加到输入框中。
                mSpanned = Html.fromHtml("", mImageGetter, null);
                mEditTextInput.getText().insert(mEditTextInput.getSelectionStart(), mSpanned);

            }
        });
        //点击输入框收回表情框
        mEditTextInput.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mGridView.getVisibility() == View.VISIBLE) {
                    mGridView.setVisibility(View.GONE);
                }
            }
        });
    }

    @Override
    public void onClick(View view) {
        mMessageAdapter = new MessageAdapter(getLayoutInflater(), mData, mImageGetter);
        switch (view.getId()) {
            case R.id.imagebutton_expression://添加表情的按钮

                if (mGridView.getVisibility() == View.VISIBLE) {
                    mGridView.setVisibility(View.GONE);
                } else {
                    mGridView.setVisibility(View.VISIBLE);
                    mInputMethodManager.hideSoftInputFromWindow(mEditTextInput.getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);

                }

                break;
            case R.id.button_left://左边的发送按钮
                showListViewLeft();
                break;
            case R.id.button_right://右边的发送按钮
                showListViewRight();
                break;
            default:
                break;

        }

    }
    /*
    发送左边消息
     */
    private void showListViewRight() {
        ChatMessage dataRight = new ChatMessage();
        dataRight.setTextViewTime(System.currentTimeMillis());
        dataRight.setTextViewHonour("营长");
        dataRight.setTextviewName("虫虫");
        /*
        判断发送的消息是否为空,如果为空则弹出提示不允许发送
        */
        if (filterHtml(Html.toHtml(mEditTextInput.getText())).equals("")) {
            Toast.makeText(getApplicationContext(), "发送的消息不能为空!", Toast.LENGTH_SHORT).show();
            return;
        }
        dataRight.setTextViewInput(filterHtml(Html.toHtml(mEditTextInput.getText())));
        dataRight.setType(MessageAdapter.SEND_RIGHT);
        mMessageAdapter.notifyDataSetChanged();
        mData.add(dataRight);
        mListView.setAdapter(mMessageAdapter);
        mListView.setSelection(mData.size() - 1);
        mEditTextInput.setText("");
    }
    /*
    发送右边消息
     */
    private void showListViewLeft() {
        ChatMessage dataLeft = new ChatMessage();
        dataLeft.setTextViewTime(System.currentTimeMillis());
        dataLeft.setTextViewHonour("营长");
        dataLeft.setTextviewName("虫虫");
        /*
        判断发送的消息是否为空,如果为空则弹出提示不允许发送
        */
        if (filterHtml(Html.toHtml(mEditTextInput.getText())).equals("")) {
            Toast.makeText(getApplicationContext(), "发送的消息不能为空!", Toast.LENGTH_SHORT).show();
            return;
        }
        //将解析的数据添加到输入框中。
        dataLeft.setTextViewInput(filterHtml(Html.toHtml(mEditTextInput.getText())));
        dataLeft.setType(MessageAdapter.SEND_LEFT);
        mMessageAdapter.notifyDataSetChanged();
        mData.add(dataLeft);
        mListView.setAdapter(mMessageAdapter);
        mListView.setSelection(mData.size() - 1);
        mEditTextInput.setText("");
    }
    public String filterHtml(String str) {
        str = str.replaceAll("<(?!br|img)[^>]+>", "").trim();
        return str;
    }
}

弹出收回表情框功能演示:
聊天界面的制作(三)——表情列表发送功能_第1张图片

发送表情,在文本任意处插入表情功能演示:
聊天界面的制作(三)——表情列表发送功能_第2张图片

聊天界面在点击表情按钮时会收回手机输入法键盘,在模拟器中无法演示,在此说明下。

你可能感兴趣的:(Android,小小项目,Android,UI设计系列)