Android仿微信公众号界面

最近在做一个关于微信公众平台服务号的小项目,主要用来实现排队叫号功能。一直都对微信公众号开发比较好奇,于是趁这次机会仔细研究了一下公众号的开发流程和逻辑架构。

微信公众平台现在分为3类:订阅号,服务号和企业号。其中,服务号和企业号的开放权限比较高,可以实现自定义菜单功能,调用摄像头以及LBS等API。

基本通信架构如图:

在项目的功能设计阶段本想搭建一个服务号Demo用来展示,但微信服务号的认证手续太麻烦,而且我也没有那个资质去开通服务号。于是打算自己做一个仿微信公众号的基本界面,先实现菜单功能,避免开发初期的公众号注册,同时也方便展示。

先上效果图:

  

1. 界面布局

主界面布局四部分,由上到下依次是:标题栏,消息列表,底部菜弹出的子菜单,底部菜单或输入栏。

主界面基本框架main.xml代码如下:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:id="@+id/main"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="#E4E4E4" > 

  <!-- 消息列表 --> 

  <ListView
    android:id="@+id/lv"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_marginBottom="50dp"
    android:layout_marginTop="10dp"
    android:cacheColorHint="#00000000"
    android:divider="#00000000"
    android:dividerHeight="20dp"
    android:scrollbars="none" >
  </ListView> 

  <!-- 点击底部菜单后弹出的子菜单 --> 

  <LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:layout_marginBottom="50dp"
    android:orientation="horizontal" > 

    <View
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="0.5" /> 

    <LinearLayout
      android:id="@+id/pop_layout1"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_gravity="bottom"
      android:layout_weight="1"
      android:orientation="vertical" >
    </LinearLayout> 

    <LinearLayout
      android:id="@+id/pop_layout2"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_gravity="bottom"
      android:layout_weight="1"
      android:orientation="vertical" >
    </LinearLayout> 

    <LinearLayout
      android:id="@+id/pop_layout3"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_gravity="bottom"
      android:layout_weight="1"
      android:orientation="vertical" >
    </LinearLayout>
  </LinearLayout> 

  <!-- 底部菜单 --> 

  <LinearLayout
    android:id="@+id/bottom_layout"
    android:layout_width="fill_parent"
    android:layout_height="50dp"
    android:layout_gravity="bottom"
    android:background="#00ffffff"
    android:orientation="vertical" > 

    <LinearLayout
      android:id="@+id/bottom_menu_layout1"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:background="#ffffff"
      android:orientation="vertical" > 

      <View
        android:layout_width="fill_parent"
        android:layout_height="1px"
        android:background="#A6A6A6" /> 

      <LinearLayout
        android:id="@+id/menu_layout"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center"
        android:orientation="horizontal" > 

        <ImageView
          android:id="@+id/keyboard"
          android:layout_width="0dp"
          android:layout_height="wrap_content"
          android:layout_marginBottom="5dp"
          android:layout_marginLeft="3dp"
          android:layout_marginRight="3dp"
          android:layout_marginTop="5dp"
          android:layout_weight="0.5"
          android:background="@drawable/keyboard" /> 

        <View
          android:layout_width="1px"
          android:layout_height="fill_parent"
          android:background="#A6A6A6" /> 

        <RelativeLayout
          android:id="@+id/btn1"
          android:layout_width="0dp"
          android:layout_height="fill_parent"
          android:layout_weight="1"
          android:background="@drawable/btn_selector" > 

          <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_margin="5dp" > 

            <TextView
              android:id="@+id/text1"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:layout_centerInParent="true"
              android:gravity="center"
              android:text="用户绑定"
              android:textColor="#000000"
              android:textSize="16sp" /> 

            <ImageView
              android:layout_width="10dp"
              android:layout_height="10dp"
              android:layout_alignParentBottom="true"
              android:layout_alignParentRight="true"
              android:src="@drawable/more_icon"
              android:visibility="invisible" />
          </RelativeLayout>
        </RelativeLayout> 

        <View
          android:layout_width="1px"
          android:layout_height="fill_parent"
          android:background="#A6A6A6" /> 

        <RelativeLayout
          android:id="@+id/btn2"
          android:layout_width="0dp"
          android:layout_height="fill_parent"
          android:layout_weight="1"
          android:background="@drawable/btn_selector" > 

          <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_margin="5dp" > 

            <TextView
              android:id="@+id/text2"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:layout_centerInParent="true"
              android:gravity="center"
              android:text="扫描签到"
              android:textColor="#000000"
              android:textSize="16sp" /> 

            <ImageView
              android:layout_width="10dp"
              android:layout_height="10dp"
              android:layout_alignParentBottom="true"
              android:layout_alignParentRight="true"
              android:src="@drawable/more_icon"
              android:visibility="invisible" />
          </RelativeLayout>
        </RelativeLayout> 

        <View
          android:layout_width="1px"
          android:layout_height="fill_parent"
          android:background="#A6A6A6" /> 

        <RelativeLayout
          android:id="@+id/btn3"
          android:layout_width="0dp"
          android:layout_height="fill_parent"
          android:layout_weight="1"
          android:background="@drawable/btn_selector" > 

          <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_margin="5dp" > 

            <TextView
              android:id="@+id/text3"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:layout_centerInParent="true"
              android:gravity="center"
              android:text="更多"
              android:textColor="#000000"
              android:textSize="16sp" /> 

            <ImageView
              android:layout_width="10dp"
              android:layout_height="10dp"
              android:layout_alignParentBottom="true"
              android:layout_alignParentRight="true"
              android:src="@drawable/more_icon"
              android:visibility="visible" />
          </RelativeLayout>
        </RelativeLayout>
      </LinearLayout>
    </LinearLayout>
  </LinearLayout> 

</FrameLayout> 

标题栏title_bar.xml布局如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="horizontal" > 

  <!-- 返回 --> 

  <ImageView
    android:id="@+id/title_bar_back_btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_centerVertical="true"
    android:layout_marginLeft="10dip"
    android:src="@drawable/back" /> 

  <!-- 服务号名称 --> 

  <TextView
    android:id="@+id/my_setting_title_tv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:text="腾讯招聘面试服务"
    android:textColor="#ffffff"
    android:textSize="20sp" /> 

  <!-- 服务号 --> 

  <ImageView
    android:id="@+id/title_bar_my"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_centerVertical="true"
    android:layout_marginRight="10dip"
    android:src="@drawable/my" /> 

</RelativeLayout> 

完成title_bar布局后,再在values\styles.xml添加自定义标题栏主题

<!-- 自定义标题栏背景颜色 -->
  <style name="CustomWindowTitleBackground">
    <item name="android:background">#32394A</item>
  </style> 

  <!-- 自定义标题栏主题 -->
  <style name="myTheme" parent="android:Theme">
    <item name="android:windowTitleSize">45dp</item>
    <item name="android:windowTitleBackgroundStyle">@style/CustomWindowTitleBackground</item>
</style>

消息列表的服务端消息item布局item_left.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="horizontal" > 

  <RelativeLayout
    android:layout_width="0dp"
    android:layout_height="fill_parent"
    android:layout_weight="4" >
    <ImageView
      android:id="@+id/server_image"
      android:layout_width="40dp"
      android:layout_height="40dp"
      android:layout_marginLeft="2dp"
      android:background="@drawable/qq"/>
    <TextView
      android:id="@+id/server_text"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginLeft="2dp"
      android:layout_toRightOf="@id/server_image"
      android:background="@drawable/text_bg_left1"
      android:gravity="center_vertical|left"
      android:textSize="16sp"
      android:textColor="#000000"/>
  </RelativeLayout> 

  <View
    android:layout_width="0dp"
    android:layout_height="fill_parent"
    android:layout_weight="1" /> 

</LinearLayout> 

消息列表的用户消息item布局item_right.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="horizontal" > 

  <View
    android:layout_width="0dp"
    android:layout_height="fill_parent"
    android:layout_weight="1" /> 

  <RelativeLayout
    android:layout_width="0dp"
    android:layout_height="fill_parent"
    android:layout_weight="4" > 

    <ImageView
      android:id="@+id/user_image"
      android:layout_width="40dp"
      android:layout_height="40dp"
      android:layout_alignParentRight="true"
      android:layout_marginRight="2dp"
      android:background="@drawable/qq" /> 

    <TextView
      android:id="@+id/user_text"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginRight="1dp"
      android:layout_toLeftOf="@id/user_image"
      android:background="@drawable/text_bg_right1"
      android:gravity="center_vertical|right"
      android:textColor="#000000"
      android:textSize="16sp" />
  </RelativeLayout> 

</LinearLayout> 

弹出的子菜单布局child_menu.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/child_layout"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:background="#FFFFFF"
  android:gravity="bottom"
  android:orientation="vertical" > 

  <RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" > 

    <Button
      android:id="@+id/test1"
      android:layout_width="wrap_content"
      android:layout_height="45dp"
      android:background="@drawable/btn_selector"
      android:paddingLeft="10dp"
      android:paddingRight="10dp"
      android:text="进度查询"
      android:textColor="#000000"
      android:textSize="16sp" /> 

    <View
      android:layout_width="wrap_content"
      android:layout_height="1px"
      android:layout_alignLeft="@id/test1"
      android:layout_alignRight="@id/test1"
      android:layout_below="@id/test1"
      android:background="#E4E4E4" />
  </RelativeLayout> 

  <RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" > 

    <Button
      android:id="@+id/test1"
      android:layout_width="wrap_content"
      android:layout_height="45dp"
      android:background="@drawable/btn_selector"
      android:paddingLeft="10dp"
      android:paddingRight="10dp"
      android:text="使用帮助"
      android:textColor="#000000"
      android:textSize="16sp" /> 

    <View
      android:layout_width="wrap_content"
      android:layout_height="1px"
      android:layout_alignLeft="@id/test1"
      android:layout_alignRight="@id/test1"
      android:layout_below="@id/test1"
      android:background="#E4E4E4" />
  </RelativeLayout> 

  <RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" > 

    <Button
      android:id="@+id/test1"
      android:layout_width="wrap_content"
      android:layout_height="45dp"
      android:background="@drawable/btn_selector"
      android:paddingLeft="10dp"
      android:paddingRight="10dp"
      android:text="联系我们"
      android:textColor="#000000"
      android:textSize="16sp" /> 

    <View
      android:layout_width="wrap_content"
      android:layout_height="1px"
      android:layout_alignLeft="@id/test1"
      android:layout_alignRight="@id/test1"
      android:layout_below="@id/test1"
      android:background="#E4E4E4" />
  </RelativeLayout> 

</LinearLayout> 

由底部菜单切换到输入框,输入框bottom_menu_layout2.xml布局如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical" > 

  <LinearLayout
    android:id="@+id/bottom_menu_layout2"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#ffffff"
    android:orientation="vertical" > 

    <View
      android:layout_width="fill_parent"
      android:layout_height="1px"
      android:background="#A6A6A6" /> 

    <LinearLayout
      android:id="@+id/menu_layout"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:gravity="center"
      android:orientation="horizontal" > 

      <!-- 左侧切换菜单按钮 --> 

      <ImageView
        android:id="@+id/menu"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="5dp"
        android:layout_marginLeft="3dp"
        android:layout_marginRight="3dp"
        android:layout_marginTop="5dp"
        android:layout_weight="0.5"
        android:background="@drawable/menu" /> 

      <View
        android:layout_width="1px"
        android:layout_height="fill_parent"
        android:background="#A6A6A6" /> 

      <RelativeLayout
        android:id="@+id/btn1"
        android:layout_width="0dp"
        android:layout_height="fill_parent"
        android:layout_margin="5dp"
        android:layout_weight="3"
        android:background="#ffffff" > 

        <ImageView
          android:id="@+id/voice"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_alignParentLeft="true"
          android:layout_centerInParent="true"
          android:layout_marginLeft="5dp"
          android:src="@drawable/voice" /> 

        <!-- 右侧“+”按钮或发送按钮 --> 

        <Button
          android:id="@+id/add"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_alignParentRight="true"
          android:layout_centerInParent="true"
          android:layout_marginRight="1dp"
          android:background="@drawable/add"
          android:paddingBottom="5dp"
          android:paddingLeft="8dp"
          android:paddingRight="8dp"
          android:paddingTop="5dp"
          android:text=""
          android:textColor="#ffffff"
          android:textSize="14sp" /> 

        <!-- 输入 --> 

        <RelativeLayout
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:layout_centerInParent="true"
          android:layout_marginLeft="5dp"
          android:layout_marginRight="5dp"
          android:layout_toLeftOf="@id/add"
          android:layout_toRightOf="@id/voice" > 

          <EditText
            android:id="@+id/input_text"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:background="#00000000"
            android:gravity="bottom"
            android:paddingLeft="2dp"
            android:paddingRight="2dp"
            android:text=""
            android:textColor="#000000"
            android:textSize="16sp" /> 

          <View
            android:layout_width="fill_parent"
            android:layout_height="1px"
            android:layout_below="@id/input_text"
            android:layout_marginTop="10dp"
            android:background="#A6A6A6" />
        </RelativeLayout>
      </RelativeLayout>
    </LinearLayout>
  </LinearLayout> 

</LinearLayout> 

2. 代码实现

MainActivity.java

package com.example.wxdemo; 

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; 

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView; 

public class MainActivity extends Activity implements View.OnClickListener { 

  private LinearLayout bottomLayout;// 底部菜单父框架
  private LinearLayout bottomMenuLayout1;// 底部菜单布局
  private LinearLayout bottomMenuLayout2;// 底部输入框布局
  private RelativeLayout btn1;// “用户绑定”按钮布局
  private RelativeLayout btn2;// “扫描签到”按钮布局
  private RelativeLayout btn3;// “更多”按钮布局
  private LinearLayout popLayout1;
  private LinearLayout popLayout2;
  private LinearLayout popLayout3;// 弹出的子菜单父框架布局
  private LinearLayout childLayout;// “更多”按钮的子菜单
  private ListView lv;
  private MyAdapter adapter;
  private List<Map<String, String>> listData = new ArrayList<Map<String, String>>(); 

  private ImageView keyboard;// 底部键盘切换图标
  private ImageView menu;// 底部菜单切换图标
  private Button send;// 发送按钮
  private EditText inputText;// 输入框 

  private boolean open = true;// 子菜单填充状态标记
  private boolean flag = false;// 子菜单显示状态标记
  private boolean bind = false;// 用户绑定状态标记 

  private Animation animEnter;// 底部菜单进入动画
  private Animation animExit;// 底部菜单退出动画 

  private View view;
  private View view2;
  private LayoutInflater inflater; 

  private int myID = 0; 

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
    setContentView(R.layout.main);
    getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
        R.layout.title_bar);// 自定义标题栏 

    inflater = MainActivity.this.getLayoutInflater(); 

    popLayout1 = (LinearLayout) findViewById(R.id.pop_layout1);
    popLayout2 = (LinearLayout) findViewById(R.id.pop_layout2);
    popLayout3 = (LinearLayout) findViewById(R.id.pop_layout3); 

    bottomLayout = (LinearLayout) findViewById(R.id.bottom_layout);
    bottomMenuLayout1 = (LinearLayout) findViewById(R.id.bottom_menu_layout1); 

    keyboard = (ImageView) findViewById(R.id.keyboard);
    btn1 = (RelativeLayout) findViewById(R.id.btn1);
    btn2 = (RelativeLayout) findViewById(R.id.btn2);
    btn3 = (RelativeLayout) findViewById(R.id.btn3); 

    lv = (ListView) findViewById(R.id.lv); 

    btn1.setOnClickListener(this);
    btn2.setOnClickListener(this);
    btn3.setOnClickListener(this);
    keyboard.setOnClickListener(this); 

    adapter = new MyAdapter(this, listData);
    lv.setAdapter(adapter); 

  } 

  @Override
  public void onClick(View v) {
    // TODO Auto-generated method stub
    int id = v.getId();
    switch (id) {
    case R.id.btn1:
      btn1Click();
      break;
    case R.id.btn2:
      break;
    case R.id.btn3:
      btn3Click();
      break;
    case R.id.keyboard:
      keyboardClick();
      break;
    case R.id.menu:
      menuClick();
      break;
    case R.id.add:
      sendClick();
      break;
    default:
      break;
    }
  } 

  public void btn1Click() {// 用户绑定
    Map<String, String> map = new HashMap<String, String>();
    map.put("type", "0");
    if (!bind) {
      map.put("text", "请输入您的手机号或简历ID进行帐号绑定,绑定成功后才能进行签到。");
    } else {
      map.put("text", "帐号已绑定成功,请您准时签到。");
    }
    listData.add(map);
    adapter.notifyDataSetChanged();
  } 

  public void btn2Click() {// 扫描签到
    // TODO
  } 

  public void btn3Click() {// 更多
    if (open == true) {
      view = inflater.inflate(R.layout.child_menu, popLayout3, true);
      childLayout = (LinearLayout) view.findViewById(R.id.child_layout);
      open = false;
    } 

    if (flag == false) {
      flag = true;
      childLayout.setVisibility(View.VISIBLE);
    } else {
      flag = false;
      childLayout.setVisibility(View.GONE);
    }
  } 

  public void keyboardClick() {//点击键盘按钮,由底部菜单切换为底部输入
    view2 = inflater.inflate(R.layout.bottom_menu_layout2, bottomLayout,
        true);
    bottomMenuLayout2 = (LinearLayout) view2
        .findViewById(R.id.bottom_menu_layout2);
    animEnter = AnimationUtils.loadAnimation(MainActivity.this,
        R.anim.my_pop_enter_anim);
    animExit = AnimationUtils.loadAnimation(MainActivity.this,
        R.anim.my_pop_exit_anim);
    animEnter.setStartOffset(200);
    bottomMenuLayout1.startAnimation(animExit);
    bottomMenuLayout1.setVisibility(View.GONE);
    bottomMenuLayout2.startAnimation(animEnter);
    bottomMenuLayout2.setVisibility(View.VISIBLE);
    menu = (ImageView) view2.findViewById(R.id.menu);
    inputText = (EditText) view2.findViewById(R.id.input_text);
    send = (Button) view2.findViewById(R.id.add);
    menu.setOnClickListener(this);
    send.setOnClickListener(this);
    inputClick();
  } 

  public void menuClick() {//点击菜单按钮,由底部输入框切换为底部菜单
    bottomMenuLayout2.startAnimation(animExit);
    bottomMenuLayout2.setVisibility(View.GONE);
    bottomMenuLayout1.startAnimation(animEnter);
    bottomMenuLayout1.setVisibility(View.VISIBLE);
  } 

  public void inputClick() {
    inputText.setOnFocusChangeListener(new OnFocusChangeListener() { 

      @Override
      public void onFocusChange(View v, boolean hasFocus) {
        // TODO Auto-generated method stub
        if (hasFocus) {
          send.setBackgroundResource(R.drawable.send_btn_bg);
          send.setText("发送");
        } else {
          send.setBackgroundResource(R.drawable.add);
          send.setText(" ");
        }
      }
    });
  } 

  public void sendClick() {
    String text = inputText.getEditableText().toString();
    inputText.setText("");
    if (text != null && (!text.equals(""))) {
      Map<String, String> map;
      map = new HashMap<String, String>();
      map.put("type", "1");// 消息类型,服务端为0,用户为1
      map.put("text", text);
      listData.add(map); 

      map = new HashMap<String, String>();
      map.put("type", "0");
      map.put("text", "帐号已绑定成功,请您准时签到。");
      listData.add(map);
      adapter.notifyDataSetChanged();
      bind = true;
    }
  } 

  private class MyAdapter extends BaseAdapter {
    public List<Map<String, String>> list;
    private Context context;
    private int type;
    private ListView listView; 

    public MyAdapter(Context context, List<Map<String, String>> list) {
      this.context = context;
      this.list = list;
    } 

    @Override
    public int getCount() {
      // TODO Auto-generated method stub
      return list.size();
    } 

    @Override
    public Object getItem(int position) {
      // TODO Auto-generated method stub
      return list.get(position);
    } 

    @Override
    public long getItemId(int position) {
      // TODO Auto-generated method stub
      return position;
    } 

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
      // TODO Auto-generated method stub
      ViewHolder viewHolder = null;
      Map<String, String> map = (Map<String, String>) list.get(position);
      if (map.get("type").equals("0")) {// 服务端
        if (convertView == null) {
          convertView = inflater.inflate(R.layout.item_left, parent,
              false);
          viewHolder = new ViewHolder();
          viewHolder.mTextView = (TextView) convertView
              .findViewById(R.id.server_text);
          viewHolder.mImageView = (ImageView) convertView
              .findViewById(R.id.server_image);
          convertView.setTag(viewHolder);
        } else {
          viewHolder = (ViewHolder) convertView.getTag();
        } 

        viewHolder.mTextView.setText(map.get("text")); 

      } else {// 用户
        if (convertView == null) {
          convertView = inflater.inflate(R.layout.item_right, parent,
              false);
          viewHolder = new ViewHolder();
          viewHolder.mTextView = (TextView) convertView
              .findViewById(R.id.user_text);
          viewHolder.mImageView = (ImageView) convertView
              .findViewById(R.id.user_image);
          convertView.setTag(viewHolder);
        } else {
          viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.mTextView.setText(map.get("text"));
      } 

      return convertView;
    } 

  } 

  private final class ViewHolder {
    TextView mTextView;
    ImageView mImageView;
  } 

} 

以上就是实现仿微信服务号的主要代码,菜单功能并没用完全实现,可根据实际情况和需要进行添加。同时还需注意的是,底部菜单最多为3个,每个名称限制在7个字符,包含的子菜单最多只能有5个。

(0)

相关推荐

  • Android 使用Fragment模仿微信界面的实例代码

    什么是Fragment 自从Android 3.0中引入fragments 的概念,根据词海的翻译可以译为:碎片.片段.其目的是为了解决不同屏幕分辩率的动态和灵活UI设计.大屏幕如平板小屏幕如手机,平板电脑的设计使得其有更多的空间来放更多的UI组件,而多出来的空间存放UI使其会产生更多的交互,从而诞生了fragments . fragments 的设计不需要你来亲自管理view hierarchy 的复杂变化,通过将Activity 的布局分散到frament 中,可以在运行时修改activit

  • Android App仿微信界面切换时Tab图标变色效果的制作方法

    概述 1.概述 学习Android少不了模仿各种app的界面,自从微信6.0问世以后,就觉得微信切换时那个变色的Tab图标屌屌的,今天我就带大家自定义控件,带你变色变得飞起~~ 好了,下面先看下效果图: 清晰度不太好,大家凑合看~~有木有觉得这个颜色弱爆了了的,,,下面我动动手指给你换个颜色: 有没有这个颜色比较妖一点~~~好了~下面开始介绍原理. 2.原理介绍 通过上面的效果图,大家可能也猜到了,我们的图标并非是两张图片,而是一张图,并且目标颜色是可定制的,谁让现在动不动就谈个性化呢. 那么我

  • Android仿微信语音聊天界面设计

    有段时间没有看视频了,昨天晚上抽了点空时间,又看了下鸿洋大神的视频教程,又抽时间写了个学习记录.代码和老师讲的基本一样,网上也有很多相同的博客.我只是在AndroidStudio环境下写的. --主界面代码-- public class MainActivity extends Activity { private ListView mListView; private ArrayAdapter<Recorder> mAdapter; private List<Recorder>

  • Android高仿微信5.2.1主界面及消息提醒

    好久没更新博客了,最近在做公司的项目,这也算是我接触的第一个正式项目.通过项目的检验,发现自己积累了一年的知识还是远远不够,想要提高,好的方法是 :项目+书+视频+博客.最重要一点:勤动手.最近发现了慕课网的视频,居然都是高清无码免费的!而且满满的干货!我用业余时间跟着视频中大神的讲解学习了不少知识,下面就将这些小demo与大家分享,当然,我做了一些优化,代码与视频中有些出入,但功能可以完全实现. 这是一个模仿5.2.1版本的显示界面,如下图所示: 功能及实现思路简介 主要功能很简单: 1.上面

  • Android 仿微信图像拍摄和选择界面功能(代码分享)

    插件运行后的画面如下: 下面这张图对图像进行筛选,根据照片产生的源头分(QQ和微信和相机) 点击某文件夹后,可以查看该文件夹下包含的所有的图片 图片选择界面 选中后就跳到已经选择界面的窗口,并且可以对该吃图片上传进行简要的描述 首先我想说明的是这个插件默认是不进行图片筛选的,打开app后会有几十个文件夹,但是个人认为开发中常用的图片基本都来自于QQ中拍摄的照片,微信中拍摄的照片,以及相机直接拍摄的照片,因此我对这个插件进行过滤以及文件夹名称的更改,具体做法,主要是对AlbumHelper类bui

  • Android仿微信主界面设计

    先来一张效果图 一.ActionBar的设计 首先是main.xml,先定义这些菜单,界面稍后在调整 <menu xmlns:android="http://schemas.android.com/apk/res/android" tools:context=".MainActivity"> <item android:id="@+id/action_search" android:actionViewClass="a

  • Android仿QQ、微信聊天界面长按提示框效果

    先来看看效果图 如何使用 示例代码 PromptViewHelper pvHelper = new PromptViewHelper(mActivity); pvHelper.setPromptViewManager(new ChatPromptViewManager(mActivity)); pvHelper.addPrompt(holder.itemView.findViewById(R.id.textview_content)); 使用起来还是很简单的 首先new一个PromptViewH

  • Android高仿微信聊天界面代码分享

    微信聊天现在非常火,是因其界面漂亮吗,哈哈,也许吧.微信每条消息都带有一个气泡,非常迷人,看起来感觉实现起来非常难,其实并不难.下面小编给大家分享实现代码. 先给大家展示下实现效果图: OK,下面我们来看一下整个小项目的主体结构: 下面是Activity的代码: package com.way.demo; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import jav

  • android仿微信聊天界面 语音录制功能

    本例为模仿微信聊天界面UI设计,文字发送以及语言录制UI. 1先看效果图: 第一:chat.xml设计 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" andro

  • Android仿支付宝微信支付密码界面弹窗封装dialog

    一,功能效果 二,实现过程 1,先写xml文件:dialog_keyboard.xml 注意事项 (1),密码部分用的是一个线性布局中6个TextView,并设置android:inputType="numberPassword",外框是用的一个有stroke属性的shape, (2),1-9数字是用的recycleview ,每个item的底部和右边有1dp的黑线,填充后形成分割线. (3),recycleview 要设置属性  android:overScrollMode=&quo

随机推荐