仿qq主界面的消息电话以及fragment中使用BaseExpandableListAdapter



主要有一下几点
1.只有一个activity
2.消息一个fragment,电话是另一个fragment
3.在电话fragment中使用BaseExpandableListAdapter

首先看main_activity.xml
<? xml version= "1.0"  encoding= "utf-8" ?>
<LinearLayout  xmlns: android = "http://schemas.android.com/apk/res/android"
    android :layout_width= "fill_parent"
    android :layout_height= "fill_parent"
    android :orientation= "vertical"  >
    <RelativeLayout
        android :id= "@+id/rl_header"
        android :layout_width= "fill_parent"
        android :layout_height= "48dp"
        android :background= "#777"  >

        <LinearLayout
            android :layout_width= "wrap_content"
            android :layout_height= "wrap_content"
            android :layout_centerInParent= "true"
            android :layout_centerVertical= "true"
            android :paddingLeft= "8.0dp"  >

            <Button
                android :id= "@+id/btn_message"
                android :layout_width= "70dip"
                android :layout_height= "30dip"
                android :background= "@drawable/baike_btn_pink_left_f_96"
                android :gravity= "center"
                android :text= "消息"
                android :textColor= "#df3031"
                android :textSize= "14sp"  />

            <Button
                android :id= "@+id/btn_call"
                android :layout_width= "70dip"
                android :layout_height= "30dip"
                android :background= "@drawable/baike_btn_trans_right_f_96"
                android :gravity= "center"
                android :text= "电话"
                android :textColor= "#ffffff"
                android :textSize= "14sp"  />
        </LinearLayout>
    </RelativeLayout>


    <FrameLayout
        android :id= "@+id/fl_content"
        android :layout_width= "fill_parent"
        android :layout_height= "fill_parent"  />

</LinearLayout>

这里先在最top处设置一条底色为灰色的栏,主要放置消息和电话两个按钮,下面的fragment就是我们将要布置的主要内容
先看消息的fragment-message .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" >

    <TextView
        android :layout_width= "match_parent"
        android :layout_height= "match_parent"
        android :text= "这是消息界面" />

</LinearLayout>
其实也没有什么东西就一个TextView
接下来是MainActivity.java
public class MainActivity  extends FragmentActivity {

        private Button  btn_message , btn_call ;

        private CallFragment  callFragment ;
        private MessageFragment  messageFragment ;

        public static final int  MESSAGE_FRAGMENT_TYPE 1 ;
        public static final int  CALL_FRAGMENT_TYPE 2 ;
        public int  currentFragmentType = - 1 ;

        @Override
        protected void  onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState) ;
            this.requestWindowFeature(Window. FEATURE_NO_TITLE) ;
            setContentView(R.layout. activity_main) ;

            btn_message = (Button)findViewById(R.id. btn_message) ;
            btn_call = (Button)findViewById(R.id. btn_call) ;
            btn_message.setOnClickListener( onClicker) ;
            btn_call.setOnClickListener( onClicker) ;

            /**
             * Return the FragmentManager for interacting with fragments associated with this activity.
             */
            FragmentManager fragmentManager = getSupportFragmentManager() ;
            if (savedInstanceState !=  null) {
                int type = savedInstanceState.getInt( "currentFragmentType") ;

                //Finds a fragment that was identified by the given tag either when inflated from XML or as supplied when added in a transaction.
                messageFragment = (MessageFragment)fragmentManager.findFragmentByTag( "message") ;
                callFragment = (CallFragment)fragmentManager.findFragmentByTag( "call") ;
                if(type >  0)
                    loadFragment(type) ;
           else {
                //Start a series of edit operations on the Fragments associated with this FragmentManager.
                FragmentTransaction transaction = fragmentManager
                        .beginTransaction() ;
                android.support.v4.app.Fragment mainFragment = fragmentManager.findFragmentByTag( "message") ;
                if (mainFragment !=  null) {
                    /**
                     *     replace(int containerViewId, Fragment fragment, String tag)
                     Replace an existing fragment that was added to a container.
                     */
                    transaction.replace(R.id. fl_content mainFragment) ; //tag== null
                    transaction.commit() ;
               else {
                    loadFragment( MESSAGE_FRAGMENT_TYPE) ;
                }
            }

        }

        //Save all appropriate fragment state.
        @Override
        protected void  onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState) ;
            outState.putInt( "lastFragmentTag" currentFragmentType) ;
        }

        private void  switchFragment( int type) {
            switch (type) {
                case  MESSAGE_FRAGMENT_TYPE:
                    loadFragment( MESSAGE_FRAGMENT_TYPE) ;
                    break;
                case  CALL_FRAGMENT_TYPE:
                    loadFragment( CALL_FRAGMENT_TYPE) ;
                    break;
            }

        }

        private void  loadFragment( int type) {
            FragmentManager fragmentManager = getSupportFragmentManager() ;
            FragmentTransaction transaction = fragmentManager.beginTransaction() ;
            if (type ==  CALL_FRAGMENT_TYPE) {
                if ( callFragment ==  null) {
                    callFragment new CallFragment() ;

                    transaction.add(R.id. fl_content callFragment "zhishi") ;
               else {
                    transaction.show( callFragment) ;
                }
                if ( messageFragment !=  null) {
                    transaction.hide( messageFragment) ;
                }
                currentFragmentType MESSAGE_FRAGMENT_TYPE ;
           else {
                if ( messageFragment ==  null) {
                    messageFragment new MessageFragment() ;
                    transaction.add(R.id. fl_content messageFragment "wenda") ;
               else {
                    transaction.show( messageFragment) ;
                }
                if ( callFragment !=  null) {
                    transaction.hide( callFragment) ;
                }
                currentFragmentType CALL_FRAGMENT_TYPE ;
            }
            transaction.commitAllowingStateLoss() ;
        }

        private View.OnClickListener  onClicker new View.OnClickListener() {
            @Override
            public void  onClick(View v) {
                switch (v.getId()) {
                    case R.id. btn_message:
                        btn_message.setTextColor(Color. parseColor( "#df3031")) ;
                        btn_call.setTextColor(Color. WHITE) ;
                        btn_message
                                .setBackgroundResource(R.drawable. baike_btn_pink_left_f_96) ;
                        btn_call
                                .setBackgroundResource(R.drawable. baike_btn_trans_right_f_96) ;
                        switchFragment( MESSAGE_FRAGMENT_TYPE) ;

                        break;
                    case R.id. btn_call:

                        btn_message.setTextColor(Color. WHITE) ;
                        btn_call.setTextColor(Color. parseColor( "#df3031")) ;
                        btn_message
                                .setBackgroundResource(R.drawable. baike_btn_trans_left_f_96) ;
                        btn_call
                                .setBackgroundResource(R.drawable. baike_btn_pink_right_f_96) ;
                        switchFragment( CALL_FRAGMENT_TYPE) ;

                        break;

                }
            }
        } ;

    }          
上面实现了对两个按钮的监听,以及更改了按钮的外观
并通过FragmentManage实现消息和电话界面的切换,MessageFragment.java就不给出了,主要是通过返回下面的代码实现
inflater.inflate(R.layout. fragment_message , null) ;
下面将讲解在CallFragment中使用BaseExpandableListAdapter将使用一下一下类和xml
fragment_call.xml  
group.xml group列的布局
child.xml child列的布局
CallFragment.java
MyAdapter.java 自定义继承BaseExpandanleListAdapter

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

    <ExpandableListView
        android :id= "@+id/android_list"
        android :layout_width= "match_parent"
        android :layout_height= "wrap_content"  />

    <TextView
        android :id= "@+id/tv_load_more"
        android :layout_width= "wrap_content"
        android :layout_height= "wrap_content"
        android :layout_below= "@+id/android_list"
        android :layout_centerHorizontal= "true"
        android :padding= "20dp"
        android :text= "@string/load_more"  />

</RelativeLayout>
 group.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 :layout_width= "match_parent"
        android :layout_height= "wrap_content"  >

        <TextView
            android :id= "@+id/tv_group"
            android :layout_width= "match_parent"
            android :layout_height= "wrap_content"
            android :paddingBottom= "6dp"
            android :paddingLeft= "10dp"
            android :paddingTop= "6dp"
            android :text= "@string/list"
            android :textSize= "15sp"  />
    </LinearLayout>

</LinearLayout>
child.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"  >

    <TextView
        android :id= "@+id/tv_child"
        android :layout_width= "fill_parent"
        android :layout_height= "fill_parent"
        android :paddingBottom= "10dp"
        android :paddingLeft= "60dp"
        android :paddingTop= "10dp"
        android :text= "好友列表"
        android :textSize= "20sp"  />

</LinearLayout>

既然要用到BaseExpandableListAdapte,则要先定义一个MyAdapter
public class MyAdapter  extends BaseExpandableListAdapter {

    private String[]  group ;
    private String[][]  buddy ;
    private Context  context ;
    private LayoutInflater  inflater ;

    public  MyAdapter(String[] group String[][] buddy Context context) {
        super() ;
        this. group = group ;
        this. buddy = buddy ;
        this. context = context ;
        inflater = LayoutInflater. from(context) ;
    }

    @Override
    public int  getGroupCount() {
        return  group. length ;
    }

    @Override
    public int  getChildrenCount( int groupPosition) {
        return  buddy[groupPosition]. length ;
    }

    @Override
    public Object  getGroup( int groupPosition) {
        return  group[groupPosition] ;
    }

    @Override
    public Object  getChild( int groupPosition , int childPosition) {

        return  buddy[groupPosition][childPosition] ;
    }

    @Override
    public long  getGroupId( int groupPosition) {
        return groupPosition ;
    }

    @Override
    public long  getChildId( int groupPosition , int childPosition) {
        return childPosition ;
    }

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

    @Override
    public View  getGroupView( int groupPosition , boolean isExpanded ,
                             View convertView ViewGroup parent) {
        convertView =  inflater.inflate(R.layout. group , null) ;
        TextView groupNameTextView = (TextView) convertView
                .findViewById(R.id. tv_group) ;
        ImageView ivSelector = (ImageView) convertView
                .findViewById(R.id. iv_selector) ;
        groupNameTextView.setText(getGroup(groupPosition).toString()) ;
        //ivSelector.setImageResource(R.drawable.pass);
        // 更换展开分组图片
//        if (!isExpanded) {
//            ivSelector.setImageResource(R.drawable.play);
//        }
        return convertView ;
    }

    @Override
    public View  getChildView( int groupPosition , int childPosition ,
                             boolean isLastChild View convertView ViewGroup parent) {
        convertView =  inflater.inflate(R.layout. child , null) ;
        TextView nickTextView = (TextView) convertView
                .findViewById(R.id. tv_child) ;

        nickTextView.setText(getChild(groupPosition childPosition).toString()) ;

        return convertView ;
    }

    // 子选项是否可以选择
    @Override
    public boolean  isChildSelectable( int groupPosition , int childPosition) {
        return true;
    }

}
然后再通过CallFragment使用它

public class CallFragment  extends Fragment {
    private ExpandableListView  elvCompany ;

    private TextView  tvLoadMore ;

    // 群组名称(一级条目内容)
    private String[]  group new String[] {  "我的好友" , "我的同学" } ;

    private String[][]  carsList new String[][]  { { "张三" "李四" "王五" "赵六"} ,
            { "景亮" , "叶文"} } ;

    @Override
    public View  onCreateView(LayoutInflater inflater ViewGroup container ,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout. fragment_call , null) ;

        tvLoadMore = (TextView) view.findViewById(R.id. tv_load_more) ;
        elvCompany = (ExpandableListView) view.findViewById(R.id. android_list) ;
        MyAdapter adapter =  new MyAdapter( group carsList getContext()) ;
        elvCompany.setAdapter(adapter) ;


        setListeners() ;

        return view ;
    }

    private void  setListeners() {
        // 分组展开
        elvCompany.setOnGroupClickListener( new ExpandableListView.OnGroupClickListener() {

            @Override
            public boolean  onGroupClick(ExpandableListView parent View v ,
                                        int groupPosition , long id) {
                return false;
            }
        }) ;
        // 分组关闭
        elvCompany.setOnGroupCollapseListener( new ExpandableListView.OnGroupCollapseListener() {

            @Override
            public void  onGroupCollapse( int groupPosition) {

            }
        }) ;

        // 子项点击
        elvCompany.setOnChildClickListener( new ExpandableListView.OnChildClickListener() {

            @Override
            public boolean  onChildClick(ExpandableListView parent View v ,
                                        int groupPosition , int childPosition , long id) {
                Toast. makeText(getActivity() ,
                        group[groupPosition] +  ":" carsList[groupPosition][childPosition] ,
                        Toast. LENGTH_SHORT).show() ;
                return false;
            }
        }) ;

        tvLoadMore.setOnClickListener( new View.OnClickListener() {

            @Override
            public void  onClick(View v) {
                Toast. makeText(getActivity() "没有更多数据了" Toast. LENGTH_SHORT)
                        .show() ;

            }
        }) ;

    }
}
这里还有一点没做好的就是没有将group的图标更改。
参考了不少前人的代码。抱歉直接分享,一起学习。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值