Android仿微信主界面设计

前端技术 2023/09/07 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=\"android.widget.SearchView\"
    android:icon=\"@drawable/actionbar_search_icon\"
    android:showAsAction=\"always|collapseActionView\"
    android:title=\"@string/action_search\"
    />
  <item
    android:id=\"@+id/action_add\"
    android:actionProviderClass=\"develop.niuli.com.weixin.PlusActionProvider\"
    android:icon=\"@drawable/actionbar_add_icon\"
    android:showAsAction=\"always\"
    android:title=\"@string/action_add\"
    />
  <!--在这里设置菜单.然后自定义一个menu -->
  <item
    android:id=\"@+id/action_btn01\"
    android:icon=\"@drawable/abc_ic_menu_moreoverflow_mtrl_alpha\"
    android:orderInCategory=\"2\"
    android:title=\"更多\"
    android:showAsAction=\"always\">
  <menu>
  <item
     android:id=\"@+id/action_photo\"
    android:icon=\"@drawable/ofm_photo_icon\"
    android:title=\"@string/action_photo\"
    android:showAsAction=\"never\"
    />
  <item
    android:id=\"@+id/action_connection\"
    android:icon=\"@drawable/ofm_collect_icon\"
    android:title=\"@string/action_connection\"
    android:showAsAction=\"never\"
    />
  <item
    android:id=\"@+id/action_card\"
    android:icon=\"@drawable/ofm_card_icon\"
    android:title=\"@string/action_card\"
    android:showAsAction=\"never\"
    />
  <item
    android:id=\"@+id/action_settings\"
    android:icon=\"@drawable/ofm_setting_icon\"
    android:title=\"@string/action_settings\"
    android:showAsAction=\"never\"
     />
  <item
    android:id=\"@+id/action_feed\"
    android:icon=\"@drawable/ofm_feedback_icon\"
    android:title=\"@string/action_feed\"
    android:showAsAction=\"never\"
    />
  </menu>
</item>
</menu>

1.android:actionViewClass=\"android.widget.SearchView\"调用系统的搜索栏样式,
2.android:showAsAction=\"always|collapseActionView\"使其可以铺满整个ActionBar.这样就能模仿出微信的效果了
3.再者overflow里面的带图标+title效果,需要自定义一个item包裹一个单独的menu,这样的话就不需要用代码就能实现图标+title的效果
4.android:actionProviderClass=\"develop.niuli.com.weixin.PlusActionProvider\"这个使用的ActionProvider,也就相当于自定义另一个菜单实现加号功能,而PlusActionProvider是自己单独写的一个类

/**
 *主要用于模仿微信上+号实现的菜单
 */
public class PlusActionProvider extends ActionProvider {

  private Context context;
  public PlusActionProvider(Context context) {
    super(context);
    this.context = context;
  }

  @Override
  public View onCreateActionView() {
    return null;
  }

  @Override
  public void onPrepareSubMenu(SubMenu subMenu) {
    //移除已经存在的项
    subMenu.clear();
    //为菜单添加图片和文字,并且加入监听事件
    subMenu.add(context.getString(R.string.plus_group_chat))
        .setIcon(R.drawable.ofm_group_chat_icon)
        .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
          @Override
          public boolean onMenuItemClick(MenuItem item) {
            return false;
          }
        });
    //剩下的如法炮制就好了
    subMenu.add(context.getString(R.string.plus_add_friend))
        .setIcon(R.drawable.ofm_add_icon)
        .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
          @Override
          public boolean onMenuItemClick(MenuItem item) {
            return false;
          }
        });
    subMenu.add(context.getString(R.string.plus_video_chat))
        .setIcon(R.drawable.ofm_video_icon)
        .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
          @Override
          public boolean onMenuItemClick(MenuItem item) {
            return false;
          }
        });
    subMenu.add(context.getString(R.string.plus_scan))
        .setIcon(R.drawable.ofm_qrcode_icon)
        .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
          @Override
          public boolean onMenuItemClick(MenuItem item) {
            return false;
          }
        });
    subMenu.add(context.getString(R.string.plus_take_photo))
        .setIcon(R.drawable.ofm_camera_icon)
        .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
          @Override
          public boolean onMenuItemClick(MenuItem item) {
            return false;
          }
        });
  }

  @Override
  public boolean hasSubMenu() {
    return true;
  }
}

这样的ActionBar基本实现了我们想要的功能,剩下的就差样式之类,所以修改Style.xml文件,AS里面也自带主题编辑器,暂时还没用到过,后期尝试

<resources>

  <!-- 这里可以使用官方的编译器来设置,具体还要再次学习-->
  <style name=\"App_Theme\" parent=\"@android:style/Theme.Holo.Light\">
    <!-- Customize your theme here. -->
    <item name=\"android:actionBarStyle\">@style/wexinActionBar</item>
    <item name=\"android:itemBackground\">@drawable/actionbar_bg_selector</item>
    <item name=\"android:actionBarItemBackground\">@drawable/actionbar_bg_selector</item>
    <item name=\"android:itemTextAppearance\">@style/WeChatActionBarTitleText</item>
    <item name=\"android:actionOverflowButtonStyle\">@style/WeChatActionButtonOverflow</item>
  </style>

  <style name=\"wexinActionBar\" parent=\"@android:style/Widget.Holo.ActionBar\">
    <item name=\"android:background\">#303537</item>
    <item name=\"android:titleTextStyle\">@style/WeChatActionBarTitleText</item>
  </style>
  <style name=\"WeChatActionBarTitleText\" parent=\"@android:style/TextAppearance.Holo.Widget.ActionBar.Title\">
    <item name=\"android:textColor\">#cfcfcf</item>
    <item name=\"android:textSize\">17sp</item>
  </style>

  <style name=\"WeChatActionButtonOverflow\" parent=\"android:style/Widget.Holo.ActionButton.Overflow\">
    <item name=\"android:src\">@drawable/actionbar_more_icon</item>
  </style>
</resources>

二.主界面的设计

使用PagerSlidingTabStrip+viewpager,两者会自动适配,用起来很方便.
在main_activity.xml中配置

<RelativeLayout 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\"
  xmlns:app=\"http://schemas.android.com/apk/res-auto\"
  tools:context=\".MainActivity\">
  <!--引入的类似ActionBar的一个tabs开源项目 -->
  <com.astuetz.PagerSlidingTabStrip
    android:id=\"@+id/tabs\"
    android:layout_width=\"match_parent\"
    app:pstsShouldExpand=\"true\"
    android:layout_height=\"40dp\"/>
  <android.support.v4.view.ViewPager
    android:id=\"@+id/pagers\"
    android:layout_width=\"match_parent\"
    android:layout_height=\"wrap_content\"
    android:layout_below=\"@+id/tabs\"
    />
</RelativeLayout>

然后建立三个fragment布局,放入到viewpager,下面举一个例子

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

  <TextView
    android:layout_width=\"match_parent\"
    android:layout_height=\"match_parent\"
    android:text=\"聊天界面\"
    android:gravity=\"center\"
    android:textSize=\"20sp\"
    />

</FrameLayout>

public class ChatFragment extends android.support.v4.app.Fragment {


  @Nullable
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.chatfragment_layout,container,false);
    return view;
  }
}

接下来就是在MainActivity.java中代码配置了

/**
   * tabs栏的实例
   */
  private PagerSlidingTabStrip tabs;

  /**
   * 获取当前屏幕的密度
   */
  private DisplayMetrics dm;

  /**
   * 主界面的viewpager
   */
  private ViewPager pagers;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    setOverflowShowingAlways();
    dm = getResources().getDisplayMetrics();
    pagers = (ViewPager) findViewById(R.id.pagers);
    tabs = (PagerSlidingTabStrip) findViewById(R.id.tabs);
    //这个类要继承FragmentActivity才可以有这个方法
    pagers.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));
    tabs.setViewPager(pagers);
    setTabValue();
  }

  /**
   * 对PagerSlidingTabStrip属性的修改
   */
  private void setTabValue(){
//    //设置tabs自动填充满整个屏幕,xml文件设置才有效果
//    tabs.setShouldExpand(true);
    //设置tabs的分割线透明
    tabs.setDividerColor(Color.TRANSPARENT);
    //设置tabs底部线的高度
    //TypedValue需要学习了解
    tabs.setUnderlineHeight((int) TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP, 1, dm));
    // 设置Tab Indicator的高度
    tabs.setIndicatorHeight((int) TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP, 4, dm));
    // 设置Tab标题文字的大小
    tabs.setTextSize((int) TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_SP, 16, dm));
    // 设置Tab Indicator的颜色
    tabs.setIndicatorColor(Color.parseColor(\"#45c01a\"));
    // 设置选中Tab文字的颜色 (这是我自定义的一个方法)
//    tabs.setSelectedTextColor(Color.parseColor(\"#45c01a\"));
    // 取消点击Tab时的背景色
    tabs.setTabBackground(0);
  }

可以看出来viewpager需要一个Adapter来配置其页面,而tabs需要配置viewpager,这样的话,三者就能完美的相适应.

public class ViewPagerAdapter extends FragmentPagerAdapter {

  /**
   * 聊天界面
   */
  private ChatFragment chatFragment;
  /**
   * 发现页面
   */
  private FoungFragment foundFragment;
  /**
   * 聊天界面
   */
  private ContactFragment contactFragment;

  private final String[] titles = { \"聊天\", \"发现\", \"通讯录\" };

  public ViewPagerAdapter(FragmentManager fm) {
    super(fm);
  }

  @Override
  public Fragment getItem(int position) {
    switch (position) {
      case 0:
        if (chatFragment == null) {
          chatFragment = new ChatFragment();
        }
        return chatFragment;
      case 1:
        if (foundFragment == null) {
          foundFragment = new FoungFragment();
        }
        return foundFragment;
      case 2:
        if (contactFragment == null) {
          contactFragment = new ContactFragment();
        }
        return contactFragment;
      default:
        return null;
    }
  }

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

  @Override
  public CharSequence getPageTitle(int position) {
    return titles[position];
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助。

本文地址:https://www.stayed.cn/item/18010

转载请注明出处。

本站部分内容来源于网络,如侵犯到您的权益,请 联系我

我的博客

人生若只如初见,何事秋风悲画扇。