Android视图功能总结(部分)

部分安卓功能实现过程(未完待续)

一、TabHost实现底部切换

1.布局

a、使用TabHost作为布局文件的根节点,并给其id赋值为:android:id="@android:id/tabhost"
b、用FrameLayout作为内容更换的显示节点,并给其id赋值为:android:id="@android:id/tabcontent"
c、用TabWidget作为选项卡的节点,并给其id赋值为:android:id="@android:id/tabs"。
    大致布局为:
        <TabHost>
            <FrameLayout>
            </FrameLayout>
            <TabWidget>
            </TabWidget?
        </TabHost>

2.逻辑实现

a.生成选项卡,此处的setIndicator()方法可以传入一个view布局。
        TabHost.TabSpec tabSpec1 = getTabHost().newTabSpec("clear_cache").setIndicator("缓存清理");
        TabHost.TabSpec tabSpec2 = getTabHost().newTabSpec("clear_sdCard").setIndicator("sd卡清理");
b.告知点中选项卡的后续操作(如点击打开另一个Activity)
        tabSpec1.setContent(new Intent(this,CacheClearActivity.class));
        tabSpec2.setContent(new Intent(this,SdCardCleanActivity.class));
c.将选项卡维护到host(宿主)中
    getTabHost().addTab(tabSpec1);
    getTabHost().addTab(tabSpec2);

二、SlidingDrawer实现滑动拖拽界面

该控件只能由右往左、下往上滑动,若需要滑动到一半,
    则在布局添加一个view占据一定的空间即可

1.添加SlidingDrawr标签,并添加以下属性

android:handle="@+id/handler"
android:content="@+id/content"
android:orientation="horizontal"
//horizontal代表由右往左滑动,vertical代表由下往上滑动。

2.在其中添加子控件,并给其子控件赋予同上的id属性。

<ImageView
    android:id="@id/handler"/>
<TextView
    android:id="@id/content"/>   
//android:handle="@+id/handler"  把手
//android:content="@+id/content" 抽屉

三、Fragment实现底部切换视图(类似QQ)

1.新建多个Fragment子类继承Fragment

实现其中的onCreateView方法,并在该方法中填充布局。
@Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //View view = inflater.from(R.layout.fragment1,container,false);
        View view = View.inflate(getContext(),R.layout.fragment1,null);
        return view;
    }

2.在主界面Activity

在布局xml文件中添加一个Framlayout布局标签,用此来替换各个Fragment的显示。
类文件中,通过响应不同Fragment按钮的事件来替换Framlayout中不同的碎片布局。
replaceFragment(new Fragment1());
     .
     .
     .
     private void replaceFragment(Fragment fragment){
        FragmentManager fm = getSupportFragmentManager();  //获取碎片管理器
        FragmentTransaction ft = fm.beginTransaction();     //开启碎片事务
        ft.replace(R.id.fl_fragment,fragment);              //在事务中替换碎片
        ft.commit();                                        //提交碎片
    }

3.在碎片和活动之间通信

通过方法来获取Fragment1的实例,进而在活动中调用碎片的方法。
Fragment1 fragment1 = (Fragment1)getFragmentManager()
    .findFragmentById(R.id.fragment1);
在碎片中调用getActivity()方法来获得和当前碎片相关联的活动示例。
MainActivity activity = (MainActivity)getActivity();

四、ScrollView中嵌入ListView,GridView冲突的解决(让ListView全显示出来)

1.方法一(Bug多,一般用法二):把ListView放在LinearLayout 中,再给listview一个具体的高度,就可以显示多行了

如:

<ScrollView android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout 
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ListView 
android:layout_width="fill_parent"
android:layout_height="400dp"
android:id="@+id/lv"></ListView>
</LinearLayout> 
</ScrollView>
2.方法二:自定义可适应ScrollView的ListView,定义类继承ListView,并重写onMeasure()方法。
/**
* 重写该方法,达到使ListView适应ScrollView的效果
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}

测量模式解释

五.FragmentTabHost实现底部菜单导航

1.FragmentTabHost用法

    它的子控件为TabSpec,其中有Idcator属性,再其中的View包含ImageView和TextView。
    首先继承FragmentActivity(AppCompatActivity是继承FragmentActivity的),调用setup()方法,添加TabSpec

2.Select背景选择器

1.Fragment实现步骤

布局文件布局:

<FrameLayout
        android:id="@+id/realtabcontent"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="@color/colorPrimary"></FrameLayout>
    <android.support.v4.app.FragmentTabHost
        android:id="@android:id/tabhost"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@color/white"
        >
        <!--必须写,官方要求-->
        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="0"
            ></FrameLayout>
    </android.support.v4.app.FragmentTabHost>

Activit实现逻辑:其中Tab为一个JavaBean,将一个导航view对象化(包括图标、标题及Fragment)

mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
        mTabHost.setup(this,getSupportFragmentManager(),R.id.realtabcontent);
        for(Tab tab : mTabs){
            TabHost.TabSpec tabSpec = mTabHost.newTabSpec(getString(tab.getTitle()));
            tabSpec.setIndicator(buildIndicator(tab));  //此处传入布局
            mTabHost.addTab(tabSpec,tab.getFragment(),null);
        }
        mTabHost.getTabWidget().setShowDividers(LinearLayout.SHOW_DIVIDER_NONE);  //去掉分割线
        mTabHost.setCurrentTab(0);       //设置默认选中第一个

搭建导航view

private View buildIndicator(Tab tab){
        View view = mInflater.inflate(R.layout.tab_indicator,null);
        ImageView icon_tab = (ImageView)view.findViewById(R.id.icon_tab);
        TextView tv_tab  = (TextView)view.findViewById(R.id.tv_tab);
        icon_tab.setBackgroundResource(tab.getIcon());
        tv_tab.setText(tab.getTitle());
        return view;
    }
2.按键按下及获取焦点,图片发生改变.

在drawable下新建select.xml文件,然后根据状态设置背景图片:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_focused="false" android:state_selected="false"
        android:state_pressed="false"  android:drawable="@mipmap/home_icon"/>
    <!--Selected states-->
    <item android:state_focused="false" android:state_selected="true"
        android:state_pressed="false"  android:drawable="@mipmap/home_select_icon"/>
    <!--Focused states-->
    <item android:state_focused="true" android:state_selected="false"
        android:state_pressed="false"  android:drawable="@mipmap/home_select_icon"/>
    <item android:state_focused="true" android:state_selected="true"
        android:state_pressed="false"  android:drawable="@mipmap/home_select_icon"/>
    <!--Pressed-->
    <item android:state_focused="true" android:state_pressed="true"
        android:drawable="@mipmap/home_select_icon"/>
    <item android:state_pressed="true"  android:drawable="@mipmap/home_select_icon"/>
</selector>

在Activity中导航按钮的ImageView设置为此布局文件:

icon_tab.setBackgroundResource(tab.getIcon());  //getIcon()就是R.drawable.select
3.点击实现字体颜色发生改变
在res文件夹下新建color文件夹,在其中新建selector_tab_text.xml文件,写入:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:color="#eb4f48" />
    <item android:state_active="true" android:color="#eb4f38"/>
    <item android:state_selected="false" android:color="#a9b7b7"/>
    <item android:state_active="false" android:color="#a9b7b7" />
</selector>
在布局文件中的TextView控件中添加属性:
android:textColor="@color/selector_tab_text"

3.底部菜单的几种实现方式。

TabHost + activity(弃用)
RadioButton + Fragment
FragmentTabHost + Fragment

六.toolBar的使用

布局文件的加入TooBar控件,
<!--添加导航键,只需加入属性:android:navigationIcon="@mipmap/refresh_m"-->
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:navigationIcon="@mipmap/refresh_m"
        app:title="title"
        ></android.support.v7.widget.Toolbar>
添加导航键监听事件:
toolbar = (Toolbar)findViewById(R.id.toolbar);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //导航键监听事件
                Toast.makeText(getApplicationContext(),"点击了导航键",Toast.LENGTH_SHORT).show();
            }
        });
添加并绑定menu:
toolbar.inflaterMenu(R.menu.menu_main);//R.menu.main是放在res下的menu文件夹下的
添加点击监听事件:
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                int id = item.getItemId();
                //...

                return true;
            }
        });

七.自定义ToolBar

八.使用开源项目实现图片轮播

使用方法及项目地址参看:[https://github.com/daimajia/AndroidImageSlider/wiki/Custom-Indicators](http://note.youdao.com/)

九.RecycleView实现多组列表视图展示

十.OkHttp实现网络通信并用Gson解析json数据

Picasso.with(mContext).load(urlImag).into(view);   //从网络下载图片并缓存至view

十一.Fresco图片加载组件

在5.0以下系统,Fresco将图片放到一个特别的内存区域。在图片不显示的时候,占用的内存会自动释放。给图片分配内存的方式:Ashmem(系统匿名共享内存)。支持gif格式
十二.使用xutils简化找控件的操作
@ViewInject(R.id.image_view);
在onCreate()方法中加入:
ViewUtils.inject(this);

十二.下拉刷新SwipeRefreshLayout控件

作为父控件来包含ListView、RecycleView等子控件,实现下拉刷新的刷新图标显示。
也可使用github开源的MaterialRefreshLayout控件来实现下拉刷新,上拉加载。地址:[https://github.com/android-cjj/Android-MaterialRefreshLayout](http://note.youdao.com/)

十三.封装RecycleView的Adapter并实现列表展示

**RecyclerView基本使用方法**,需为其添加的数据适配器是需要继承Recycle.Adapter,
并指定泛型一个继承自RecyclerView.ViewHolder的类,并添加构造方法对Item中的子控件进行初始化。
同时重写onCreateViewHolder()、onBindViewHolder()和getItemCount()这3个方法。

此次封装简化了RecycleView的使用,不在需要考虑ViewHolder中的多个控件属性,我们只需要自定义一个Adapter(如下面的TestBeanAdapter)继承自SimpleAdapter类,并加载自身的构造函数,同时实现其中的bindData()方法即可,即为每个Item对应的View控件绑定数据。

1.声明一个类BaseAdapter继承RecyclerView。ViewHolder。

指定泛型

public abstract class BaseAdapter<T,H extends BaseViewHolder> extends RecyclerView.Adapter<BaseViewHolder>{

    //1.数据使用泛型
    protected List<T> mDatas;
    protected LayoutInflater mInflater;
    protected Context mContext;
    protected int mLayoutResId;
    private OnItemClickListener listener;

    public interface OnItemClickListener{
        void OnClick(View view, int position);
    }
    public void setOnItemClickListener(OnItemClickListener listener){
        this.listener = listener;
    }

    public BaseAdapter(Context context, List<T> datas, int layoutResId){
        this.mDatas = datas;
        this.mContext = context;
        this.mLayoutResId = layoutResId;
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = mInflater.inflate(mLayoutResId,null,false);
        return new BaseViewHolder(view, listener);
    }

    @Override
    public void onBindViewHolder(BaseViewHolder holder, int position) {
        T t = getItem(position);

        bindData(holder,t);
    }

    @Override
    public int getItemCount() {
        return mDatas.size();
    }

    public T getItem(int postion){
        return mDatas.get(postion);
    }

    public abstract  void bindData(BaseViewHolder viewHolder, T t);
}

2.新建一个BaseViewHolder继承自RecyclerView.ViewHolder并实现OnclickListener.

public class BaseViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

    private BaseAdapter.OnItemClickListener listener;
    private SparseArray<View> views;

    public BaseViewHolder(View itemView, BaseAdapter.OnItemClickListener listener) {
        super(itemView);
        //mItemView = itemView;
        views = new SparseArray<>();
        this.listener = listener;
        itemView.setOnClickListener(this);
    }

    public View getView(int id){
        return findView(id);
    }

    public TextView getTextView(int id){
        return findView(id);
    }

    public ImageView getImageView(int id){
        return findView(id);
    }

    public Button getButtonView(int id){
        return findView(id);
    }

    private <T extends View> T findView(int id){
        View view = views.get(id);
        if(view == null){
            view = itemView.findViewById(id);
            views.put(id,view);
        }
        return (T) view;
    }


    @Override
    public void onClick(View v) {
        listener.OnClick(v,getLayoutPosition());
    }
}

3.SimpleAdapter继承BaseAdapter

为了减少一个泛型参数。并添加构造函数,初始化参数。
public abstract class SimpleAdapter<T> extends BaseAdapter<T,BaseViewHolder>{
    public SimpleAdapter(Context context, List<T> datas, int layoutResId) {
        super(context, datas, layoutResId);
    }
}

4.新建一个TestBeanAdapter 继承自SimpleAdapter对象即。

添加构造函数,并覆写bindData()方法,即在此方法中为每个Item中的View进行初始化赋值。

public class TestBeanAdapter extends SimpleAdapter<TestBean>{      //新建的TestBeanAdapter就直接使用定好的布局文件
    public TestBeanAdapter(Context context, List<TestBean> datas) {
        super(context, datas, R.layout.test_adapter_item);
    }

    @Override
    public void bindData(BaseViewHolder viewHolder, TestBean testBean) {
    //为每个Item添加并绑定数据
        TextView tv_test_item_left = (TextView) viewHolder.getView(R.id.tv_test_item_left);       //条目布局文件中的子控件
        TextView tv_test_item_right = viewHolder.getTextView(R.id.tv_test_item_right);  //直接用在ViewHolder中封装好的函数
        tv_test_item_left.setText(testBean.getName());
        tv_test_item_right.setText(testBean.getSex());
    }
}

5.使用方法

使用时需新建步骤(1、2)或(1、2、3、4)中的类文件,对应使用下面(1)或(2)的使用方法。
注意:在使用LinearLayoutManager时会出现每个Item只能占据一部分,即不能适配Item的布局(原因暂时未知,有人解释是RecyclerView的bug),将其改为GridLayoutManager就能进行适配布局。
其中参数datas,为TestBean的一个数组,而TestBean是一个将Item中的View进行赋值而保存的JavaBean。
rl_test = (RecyclerView)mView.findViewById(R.id.rl_test);
        GridLayoutManager layoutManager = new GridLayoutManager(getContext(),1);  
        //用LinearLayoutManager会出现问题,每个Item只会占据有内容的一部分
        //LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
        rl_test.setLayoutManager(layoutManager);
for(int i = 0;i<10;i++){
            TestBean bean = new TestBean("sannas"+ i,"man");
            datas.add(bean);
        }
public class TestBean {
    private String name;
    private String sex;

    public TestBean(String name, String sex) {
        this.name = name;
        this.sex = sex;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
(1)直接使用BaseAdapter。
BaseAdapter<TestBean,BaseViewHolder> mAdatper = new BaseAdapter<TestBean,BaseViewHolder>(getContext(),datas,R.layout.test_adapter_item) {
            //R.layout.test_adapter_item为每个条目的布局文件
            @Override
            public void bindData(BaseViewHolder viewHolder, TestBean testBean) {
                TextView tv_test_item_left = (TextView) viewHolder.getView(R.id.tv_test_item_left);       //条目布局文件中的子控件
                TextView tv_test_item_right = viewHolder.getTextView(R.id.tv_test_item_right);  //直接用在ViewHolder中封装好的函数
                tv_test_item_left.setText(testBean.getName());
                tv_test_item_right.setText(testBean.getSex());
            }
        };
        mAdatper.setOnItemClickListener(new BaseAdapter.OnItemClickListener() {
            @Override
            public void OnClick(View view, int position) {
                //
                Toast.makeText(getActivity(),"点击了第"+ position +"个Item",Toast.LENGTH_SHORT).show();
            }
        });

        rl_test.setAdapter(mAdatper);
(2)使用将Item的View对象的值实例化成为一个Bean对象之后并进行初始化之后的TestBeanAdapter。
 TestBeanAdapter mAdatper = new TestBeanAdapter(getContext(),datas);
 mAdatper.setOnItemClickListener(new BaseAdapter.OnItemClickListener() {
            @Override
            public void OnClick(View view, int position) {
                Toast.makeText(getActivity(),"点击了第"+ position +"个Item",Toast.LENGTH_SHORT).show();
            }
        });
        rl_test.setAdapter(mAdatper);

Switch控件

使用下面两个属性可以改变开关的按钮及北京图片
android:thumb="@drawable/bike"
android:track="@drawable/boat"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值