A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

【济南中心】Android课程同步笔记Day1:智慧北京

主界面搭建: 底部Tab + 侧滑菜单
底部Tab的实现
通过观察效果图不难发现,要实现底部tab,一般我们可以通过RadioGroup + RadioButton组合实现
首先创建项目,在activity_main.xml文件添加5个RadioButton,由于每个tab都有相同的样式,这里针对样式进行抽取:
在res/values/styles.xml文件中相同样式抽取
[XML] 纯文本查看 复制代码
<style name="tab_rb_style">
    <item name="android:layout_width">0dp</item>
    <item name="android:layout_weight">1</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:gravity">center</item>
    <item name="android:button">@null</item>
    <item name="android:textSize">12sp</item>
    <item name="android:drawablePadding">5dp</item>
    <item name="android:paddingTop">5dp</item>
    <item name="android:paddingBottom">5dp</item>
    <item name="android:textColor">@color/tab_txt_selector</item>
</style>

由于每个tab都有相同的文字颜色选择器。因此,给属性android:textColor设置的文字颜色选择器
[XML] 纯文本查看 复制代码
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true" android:color="#f00"/>
    <item  android:color="#fff"/>
</selector>

然后在【文件styles.xml】中给属性android:textColor设置的文字颜色选择器
[XML] 纯文本查看 复制代码
<style name="tab_rb_style">
    <item name="android:layout_width">0dp</item>
    <item name="android:layout_weight">1</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:gravity">center</item>
    <item name="android:button">@null</item>
    <item name="android:textSize">12sp</item>
    <item name="android:drawablePadding">5dp</item>
    <item name="android:paddingTop">5dp</item>
    <item name="android:paddingBottom">5dp</item>
    <item name="android:textColor">@color/tab_txt_selector</item>
</style>

由于每个tab的在不同状态,图片不一样,因此每个tab的图片,通过图片选择器来实现,这里定义了5个选择器:res/drawable目录下创建文件home_tab_selector.xml,以此类推。
[XML] 纯文本查看 复制代码
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true" android:drawable="@drawable/home_press"/>
    <item  android:drawable="@drawable/home"/>
</selector>
我们通过每个radiobutton属性android:drawableTop为每个radiobutton添加选择器。
[XML] 纯文本查看 复制代码
<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="com.itheima.bottomtabdemo.MainActivity">
   <RadioGroup
       android:id="@+id/rg_tab"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:orientation="horizontal"
       android:background="@drawable/bottom_tab_bg">
       <RadioButton
           android:id="@+id/rb_home"
           android:drawableTop="@drawable/home_tab_selector"
           android:checked="true"
           android:text="首页"
           style="@style/tab_rb_style" />
       <RadioButton
           android:id="@+id/rb_newscenter"
           android:drawableTop="@drawable/newscenter_tab_selector"
           android:text="新闻中心"
           style="@style/tab_rb_style" />
       <RadioButton
           android:id="@+id/rb_smartservice"
           android:drawableTop="@drawable/smartservice_tab_selector"
           android:text="智慧服务"
           style="@style/tab_rb_style" />
       <RadioButton
           android:id="@+id/rb_govaffairs"
           android:drawableTop="@drawable/govaffairs_tab_selector"
           android:text="政务"
           style="@style/tab_rb_style" />
       <RadioButton
           android:id="@+id/rb_setting"
           android:drawableTop="@drawable/setting_tab_selector"
           android:text="设置"
           style="@style/tab_rb_style" />
   </RadioGroup>
</LinearLayout>
ViewPager加载Fragment
Viewpager要实现界面,需要填充对应的Fragment。因此这里我们需要创建5fragment,分别为首页,新闻中心,智慧服务,政务和设置界面文件HomeTabFragment.java实例
[Java] 纯文本查看 复制代码
public class NewsCenterFragment extends Fragment {

    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        TextView tv = new TextView(getContext());
        tv.setTextSize(20);
        tv.setTextColor(Color.RED);
        tv.setGravity(Gravity.CENTER);
        tv.setText("首页");
        return tv;
    }
}
在ViewPager上展示fragment,需要通过FragmentPagerApdater适配器来初始化每个fragment。因此我们需要创建TabAdapter适配器。创建TabAdapter适配器需要继承FragmentPagerApdater
[Java] 纯文本查看 复制代码
public class TabAdapter extends FragmentPagerAdapter {

    private List<Fragment> fragments;

    public TabAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);
        this.fragments = fragments;
    }

    //获取对应位置的Fragment
    @Override
    public Fragment getItem(int position) {
        return fragments.get(position);
    }

    //页面的数量
    @Override
    public int getCount() {
        return fragments.size();
    }
}
最后通过调用ViewPager 的 setAdapter方法,将Fragment和ViewPager进行绑定,以MainActivity.java实例
[Java] 纯文本查看 复制代码
public class MainActivity extends AppCompatActivity{

    private ViewPager vp;
    private List<Fragment> fragments;
    private RadioButton rb_newscenter;
    private RadioButton rb_smartservice;
    private RadioButton rb_govaffairs;
    private RadioButton rb_setting;
    private RadioButton rb_home;

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

        initView();
        initVP();

    }



    //初始化ViewPager
    private void initVP() {
        fragments = new ArrayList<>();
        fragments.add(new HomeTabFragment());
        fragments.add(new NewsCenterTabFragment());
        fragments.add(new SmartServiceTabFragment());
        fragments.add(new GovaffairsTabFragment());
        fragments.add(new SettingTabFragment());
        TabAdapter adapter = new TabAdapter(getSupportFragmentManager(),fragments);
        vp.setAdapter(adapter);

    }

    //初始化控件
    private void initView() {
        vp = (ViewPager) findViewById(R.id.vp);
        RadioGroup rg_tab = (RadioGroup) findViewById(R.id.rg_tab);

        rb_home = (RadioButton) findViewById(R.id.rb_home);
        rb_newscenter = (RadioButton) findViewById(R.id.rb_newscenter);
        rb_smartservice = (RadioButton) findViewById(R.id.rb_smartservice);
        rb_govaffairs = (RadioButton) findViewById(R.id.rb_govaffairs);
        rb_setting = (RadioButton) findViewById(R.id.rb_setting);
    }

    }
RaidoGroup设置监听切换ViewPager的页面
第一步:给RadioGroup设置切换监听
当我们切换radiobutton时,切换对应的fragment,需要给RadioGroup监听
[Java] 纯文本查看 复制代码
public class MainActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener {

    private ViewPager vp;
    private List<Fragment> fragments;
    private RadioButton rb_newscenter;
    private RadioButton rb_smartservice;
    private RadioButton rb_govaffairs;
    private RadioButton rb_setting;
    private RadioButton rb_home;

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

        initView();
        initVP();

    }

    //初始化ViewPager
    private void initVP() {
        fragments = new ArrayList<>();
        fragments.add(new HomeTabFragment());
        fragments.add(new NewsCenterTabFragment());
        fragments.add(new SmartServiceTabFragment());
        fragments.add(new GovaffairsTabFragment());
        fragments.add(new SettingTabFragment());
        TabAdapter adapter = new TabAdapter(getSupportFragmentManager(),fragments);
        vp.setAdapter(adapter);

    }

    //初始化控件
    private void initView() {
        vp = (ViewPager) findViewById(R.id.vp);
        RadioGroup rg_tab = (RadioGroup) findViewById(R.id.rg_tab);
        //设置选择改变监听
        rg_tab.setOnCheckedChangeListener(this);

        rb_home = (RadioButton) findViewById(R.id.rb_home);
        rb_newscenter = (RadioButton) findViewById(R.id.rb_newscenter);
        rb_smartservice = (RadioButton) findViewById(R.id.rb_smartservice);
        rb_govaffairs = (RadioButton) findViewById(R.id.rb_govaffairs);
        rb_setting = (RadioButton) findViewById(R.id.rb_setting);
    }

    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
     
    }

   }
第二步:监听选中事件
[Java] 纯文本查看 复制代码
public class MainActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener, ViewPager.OnPageChangeListener {

    private ViewPager vp;
    private List<Fragment> fragments;
    private RadioButton rb_newscenter;
    private RadioButton rb_smartservice;
    private RadioButton rb_govaffairs;
    private RadioButton rb_setting;
    private RadioButton rb_home;

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

        initView();
        initVP();
    }

    //初始化ViewPager
    private void initVP() {
        fragments = new ArrayList<>();
        fragments.add(new HomeTabFragment());
        fragments.add(new NewsCenterTabFragment());
        fragments.add(new SmartServiceTabFragment());
        fragments.add(new GovaffairsTabFragment());
        fragments.add(new SettingTabFragment());
        TabAdapter adapter = new TabAdapter(getSupportFragmentManager(),fragments);
        vp.setAdapter(adapter);
        //给ViewPager设置页面滑动改变监听
        vp.addOnPageChangeListener(this);
    }

    //初始化控件
    private void initView() {
        vp = (ViewPager) findViewById(R.id.vp);
        RadioGroup rg_tab = (RadioGroup) findViewById(R.id.rg_tab);
        //设置选择改变监听
        rg_tab.setOnCheckedChangeListener(this);

        rb_home = (RadioButton) findViewById(R.id.rb_home);
        rb_newscenter = (RadioButton) findViewById(R.id.rb_newscenter);
        rb_smartservice = (RadioButton) findViewById(R.id.rb_smartservice);
        rb_govaffairs = (RadioButton) findViewById(R.id.rb_govaffairs);
        rb_setting = (RadioButton) findViewById(R.id.rb_setting);
    }

    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        int item = 0;
        switch (checkedId){
            case R.id.rb_home:
                item = 0;
                break;
            case R.id.rb_newscenter:
                item = 1;
                break;
            case R.id.rb_smartservice:
                item = 2;
                break;
            case R.id.rb_govaffairs:
                item = 3;
                break;
            case R.id.rb_setting:
                item = 4;
                break;
        }
        //ViewPager切换到对应的页面
        vp.setCurrentItem(item,false);//false 不需要Viewpager页面切换的时候有滑动的动画
    }
}
第三步:ViewPager切换Fragment界面
[Java] 纯文本查看 复制代码
public class MainActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener, ViewPager.OnPageChangeListener {

    private ViewPager vp;
    private List<Fragment> fragments;
    private RadioButton rb_newscenter;
    private RadioButton rb_smartservice;
    private RadioButton rb_govaffairs;
    private RadioButton rb_setting;
    private RadioButton rb_home;

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

        initView();
        initVP();
    }

    //初始化ViewPager
    private void initVP() {
        fragments = new ArrayList<>();
        fragments.add(new HomeTabFragment());
        fragments.add(new NewsCenterTabFragment());
        fragments.add(new SmartServiceTabFragment());
        fragments.add(new GovaffairsTabFragment());
        fragments.add(new SettingTabFragment());
        TabAdapter adapter = new TabAdapter(getSupportFragmentManager(),fragments);
        vp.setAdapter(adapter);
        //给ViewPager设置页面滑动改变监听
        vp.addOnPageChangeListener(this);
    }

    //初始化控件
    private void initView() {
        vp = (ViewPager) findViewById(R.id.vp);
        RadioGroup rg_tab = (RadioGroup) findViewById(R.id.rg_tab);
        //设置选择改变监听
        rg_tab.setOnCheckedChangeListener(this);

        rb_home = (RadioButton) findViewById(R.id.rb_home);
        rb_newscenter = (RadioButton) findViewById(R.id.rb_newscenter);
        rb_smartservice = (RadioButton) findViewById(R.id.rb_smartservice);
        rb_govaffairs = (RadioButton) findViewById(R.id.rb_govaffairs);
        rb_setting = (RadioButton) findViewById(R.id.rb_setting);
    }

    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        int item = 0;
        switch (checkedId){
            case R.id.rb_home:
                item = 0;
                break;
            case R.id.rb_newscenter:
                item = 1;
                break;
            case R.id.rb_smartservice:
                item = 2;
                break;
            case R.id.rb_govaffairs:
                item = 3;
                break;
            case R.id.rb_setting:
                item = 4;
                break;
        }
        //ViewPager切换到对应的页面
        vp.setCurrentItem(item,false);//false 不需要Viewpager页面切换的时候有滑动的动画
    }
}
ViewPager页面滑动修改对应的tab选择
第一步:给ViewPager设置监听
[Java] 纯文本查看 复制代码
public class MainActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener, ViewPager.OnPageChangeListener {

    private ViewPager vp;
    private List<Fragment> fragments;
    private RadioButton rb_newscenter;
    private RadioButton rb_smartservice;
    private RadioButton rb_govaffairs;
    private RadioButton rb_setting;
    private RadioButton rb_home;

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

        initView();
        initVP();

    }




    //初始化ViewPager
    private void initVP() {
        fragments = new ArrayList<>();
        fragments.add(new HomeTabFragment());
        fragments.add(new NewsCenterTabFragment());
        fragments.add(new SmartServiceTabFragment());
        fragments.add(new GovaffairsTabFragment());
        fragments.add(new SettingTabFragment());
        TabAdapter adapter = new TabAdapter(getSupportFragmentManager(),fragments);
        vp.setAdapter(adapter);
        //给ViewPager设置页面滑动改变监听
        vp.addOnPageChangeListener(this);
    }

    //初始化控件
    private void initView() {
        vp = (ViewPager) findViewById(R.id.vp);
        RadioGroup rg_tab = (RadioGroup) findViewById(R.id.rg_tab);
        //设置选择改变监听
        rg_tab.setOnCheckedChangeListener(this);

        rb_home = (RadioButton) findViewById(R.id.rb_home);
        rb_newscenter = (RadioButton) findViewById(R.id.rb_newscenter);
        rb_smartservice = (RadioButton) findViewById(R.id.rb_smartservice);
        rb_govaffairs = (RadioButton) findViewById(R.id.rb_govaffairs);
        rb_setting = (RadioButton) findViewById(R.id.rb_setting);
    }

    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        int item = 0;
        switch (checkedId){
            case R.id.rb_home:
                item = 0;
                break;
            case R.id.rb_newscenter:
                item = 1;
                break;
            case R.id.rb_smartservice:
                item = 2;
                break;
            case R.id.rb_govaffairs:
                item = 3;
                break;
            case R.id.rb_setting:
                item = 4;
                break;
        }
        //ViewPager切换到对应的页面
        vp.setCurrentItem(item,false);//false 不需要Viewpager页面切换的时候有滑动的动画
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    }
    @Override
    public void onPageSelected(int position) {
           }
    @Override
    public void onPageScrollStateChanged(int state) {

    }
}
第二步:监听ViewPager的滑动事件
实现ViewPager滑动监听的回调方法,监听滑动事件,在onPageSelected方法中,根据选中的index,切换底部的tab
[Java] 纯文本查看 复制代码
public class MainActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener, ViewPager.OnPageChangeListener {

    private ViewPager vp;
    private List<Fragment> fragments;
    private RadioButton rb_newscenter;
    private RadioButton rb_smartservice;
    private RadioButton rb_govaffairs;
    private RadioButton rb_setting;
    private RadioButton rb_home;

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

        initView();
        initVP();
        initSlidingMenu();
    }



    //初始化ViewPager
    private void initVP() {
        fragments = new ArrayList<>();
        fragments.add(new HomeTabFragment());
        fragments.add(new NewsCenterTabFragment());
        fragments.add(new SmartServiceTabFragment());
        fragments.add(new GovaffairsTabFragment());
        fragments.add(new SettingTabFragment());
        TabAdapter adapter = new TabAdapter(getSupportFragmentManager(),fragments);
        vp.setAdapter(adapter);
        //给ViewPager设置页面滑动改变监听
        vp.addOnPageChangeListener(this);
    }

    //初始化控件
    private void initView() {
        vp = (ViewPager) findViewById(R.id.vp);
        RadioGroup rg_tab = (RadioGroup) findViewById(R.id.rg_tab);
        //设置选择改变监听
        rg_tab.setOnCheckedChangeListener(this);

        rb_home = (RadioButton) findViewById(R.id.rb_home);
        rb_newscenter = (RadioButton) findViewById(R.id.rb_newscenter);
        rb_smartservice = (RadioButton) findViewById(R.id.rb_smartservice);
        rb_govaffairs = (RadioButton) findViewById(R.id.rb_govaffairs);
        rb_setting = (RadioButton) findViewById(R.id.rb_setting);
    }

    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        int item = 0;
        switch (checkedId){
            case R.id.rb_home:
                item = 0;
                break;
            case R.id.rb_newscenter:
                item = 1;
                break;
            case R.id.rb_smartservice:
                item = 2;
                break;
            case R.id.rb_govaffairs:
                item = 3;
                break;
            case R.id.rb_setting:
                item = 4;
                break;
        }
        //ViewPager切换到对应的页面
        vp.setCurrentItem(item,false);//false 不需要Viewpager页面切换的时候有滑动的动画
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    }
    @Override
    public void onPageSelected(int position) {
        switch (position){
            case 0:
                rb_home.setChecked(true);
                break;
            case 1:
                rb_newscenter.setChecked(true);
                break;
            case 2:
                rb_smartservice.setChecked(true);
                break;
            case 3:
                rb_govaffairs.setChecked(true);
                break;
            case 4:
                rb_setting.setChecked(true);
                break;
        }
    }
    @Override
    public void onPageScrollStateChanged(int state) {

    }
}
侧滑菜单- SlidingMenu的引入
[Java] 纯文本查看 复制代码
public class MainActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener, ViewPager.OnPageChangeListener {

    private ViewPager vp;
    private List<Fragment> fragments;
    private RadioButton rb_newscenter;
    private RadioButton rb_smartservice;
    private RadioButton rb_govaffairs;
    private RadioButton rb_setting;
    private RadioButton rb_home;

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

        initView();
        initVP();
        initSlidingMenu();
    }

    //初始化侧滑菜单
    private void initSlidingMenu() {
        //创建侧滑菜单
        SlidingMenu slidingmenu = new SlidingMenu(this);
        //设置菜单从左边滑出
        slidingmenu.setMode(SlidingMenu.LEFT);
        //设置全屏可以滑出菜单
        slidingmenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
        //设置侧滑菜单的宽度
        slidingmenu.setBehindWidth(250);
        //把侧滑菜单附加在Activity里面
        slidingmenu.attachToActivity(this,SlidingMenu.SLIDING_CONTENT);
        //设置侧滑菜单的布局
        slidingmenu.setMenu(R.layout.main_menu);
    }


    //初始化ViewPager
    private void initVP() {
        fragments = new ArrayList<>();
        fragments.add(new HomeTabFragment());
        fragments.add(new NewsCenterTabFragment());
        fragments.add(new SmartServiceTabFragment());
        fragments.add(new GovaffairsTabFragment());
        fragments.add(new SettingTabFragment());
        TabAdapter adapter = new TabAdapter(getSupportFragmentManager(),fragments);
        vp.setAdapter(adapter);
        //给ViewPager设置页面滑动改变监听
        vp.addOnPageChangeListener(this);
    }

    //初始化控件
    private void initView() {
        vp = (ViewPager) findViewById(R.id.vp);
        RadioGroup rg_tab = (RadioGroup) findViewById(R.id.rg_tab);
        //设置选择改变监听
        rg_tab.setOnCheckedChangeListener(this);

        rb_home = (RadioButton) findViewById(R.id.rb_home);
        rb_newscenter = (RadioButton) findViewById(R.id.rb_newscenter);
        rb_smartservice = (RadioButton) findViewById(R.id.rb_smartservice);
        rb_govaffairs = (RadioButton) findViewById(R.id.rb_govaffairs);
        rb_setting = (RadioButton) findViewById(R.id.rb_setting);
    }

    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        int item = 0;
        switch (checkedId){
            case R.id.rb_home:
                item = 0;
                break;
            case R.id.rb_newscenter:
                item = 1;
                break;
            case R.id.rb_smartservice:
                item = 2;
                break;
            case R.id.rb_govaffairs:
                item = 3;
                break;
            case R.id.rb_setting:
                item = 4;
                break;
        }
        //ViewPager切换到对应的页面
        vp.setCurrentItem(item,false);//false 不需要Viewpager页面切换的时候有滑动的动画
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    }
    @Override
    public void onPageSelected(int position) {
        switch (position){
            case 0:
                rb_home.setChecked(true);
                break;
            case 1:
                rb_newscenter.setChecked(true);
                break;
            case 2:
                rb_smartservice.setChecked(true);
                break;
            case 3:
                rb_govaffairs.setChecked(true);
                break;
            case 4:
                rb_setting.setChecked(true);
                break;
        }
    }
    @Override
    public void onPageScrollStateChanged(int state) {

    }
}
事件传递机制
[Java] 纯文本查看 复制代码
public boolean dispatchTouchEvent(MotionEvent ev)
如果 return true,事件会分发给当前 View 并由dispatchTouchEvent 方法进行处理,同时事件会停止向下传递;
如果 return false,事件分发分为两种情况:
如果当前 View 获取的事件直接来自 Activity,则会将事件返回给Activity 的 onTouchEvent 进行消费;
如果当前 View 获取的事件来自外层父控件,则会将事件返回给父 View 的  onTouchEvent 进行消费。
如果返回系统默认的 super.dispatchTouchEvent(ev),事件会自动的分发给当前 View 的 onInterceptTouchEvent 方法。
[Java] 纯文本查看 复制代码
public boolean onInterceptTouchEvent(MotionEvent ev)
return true;表示是该控件拦截此事件
如果 onInterceptTouchEvent返回 true,则表示将事件进行拦截,并将拦截到的事件交由当前 View 的 onTouchEvent 进行处理;
如果 onInterceptTouchEvent返回 false,则表示将事件放行,当前 View 上的事件会被传递到子 View 上,再由子 View 的dispatchTouchEvent 来开始这个事件的分发;
如果onInterceptTouchEvent 返回 super.onInterceptTouchEvent(ev),事件默认会被拦截,并将拦截到的事件交由当前 View 的 onTouchEvent 进行处理。
[Java] 纯文本查看 复制代码
public boolean onTouchEvent(MotionEvent event)
Activity ViewGroup   View 该方法的返回值是提供给dispatchTouchEvent()的返回值
如果事件传递到当前 View 的 onTouchEvent 方法,而该方法返回了 false,那么这个事件会从当前 View 向上传递,并且都是由上层 View 的 onTouchEvent 来接收,如果传递到上面的 onTouchEvent 也返回 false,这个事件就会“消失”,而且接收不到下一次事件。
如果返回了 true 则会接收并消费该事件。
如果返回 super.onTouchEvent(ev)默认处理事件的逻辑和返回 false 时相同。
事件传递案例模型设计

自定义ViewGroup
[Java] 纯文本查看 复制代码
public class MyViewGroup extends ViewGroup {

    public MyViewGroup(Context context) {
        super(context);
    }

    public MyViewGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    //测量
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        View view = getChildAt(0);
        view.measure(widthMeasureSpec,heightMeasureSpec);
    }

    //布局
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        View view = getChildAt(0);
        view.layout(l,t,r,b);
    }
自定View
[Java] 纯文本查看 复制代码
public class MyView extends View {

    private Paint mPaint;

    public MyView(Context context) {
        this(context,null);
    }

    public MyView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //初始化画笔
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.RED);
        mPaint.setTextSize(15);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawText("事件传递",0,150,mPaint);
    }
事件传递简单认识

子控件请求父控件不要拦截事件
[AppleScript] 纯文本查看 复制代码
public class MyView extends View {

    private Paint mPaint;

    public MyView(Context context) {
        this(context,null);
    }

    public MyView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //初始化画笔
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.RED);
        mPaint.setTextSize(15);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawText("事件传递",0,150,mPaint);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        //请求父控件不要拦截事件
        getParent().requestDisallowInterceptTouchEvent(true);
        Log.i("TAG","MyView                  dispatchTouchEvent");
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                Log.i("TAG","MainActivity          按下");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.i("TAG","MainActivity          移动");
                break;
            case MotionEvent.ACTION_UP:
                Log.i("TAG","MainActivity          弹起");
                break;
        }
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i("TAG","MyView                  onTouchEvent");
        return true;//return true 表示 MyView处理事件
    }
}
注意:
在编写自定义ViewGroup的时候不要直接去拦截所有的事件
[Java] 纯文本查看 复制代码
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    return true;//拦击事件
}

像这样写那么这样的自定义控件是没有意义的,因为后面的子控件无法处理任何事件。

事件传递源码
ViewGroup源码
View的源码
强调:
onTouchEvent()方法的返回值决定了dispatchTouchEvent()的返回值。

但是最终决定事件是否继续往下传递还是由dispatchTouchEvent()方法来决定。

默认事件传递的整个过程细节

禁用主界面ViewPager的滑动事件
[Java] 纯文本查看 复制代码
public class NoScrollViewPager extends ViewPager {
    public NoScrollViewPager(Context context) {
        super(context);
    }

    public NoScrollViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    //拦截事件   默认  ViewPager会拦截掉Move UP 事件   不要拦截事件
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return false;
    }

    //处理事件  不要处理事件
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return false;
    }
}
ButterKnift8的使用
1.在project-level  build.gradle文件中dependencies节点添加如下代码
[Java] 纯文本查看 复制代码
                // Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.2'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

在module-level  build.gradle文件中dependencies节点添加如下代码
[Java] 纯文本查看 复制代码
apply plugin: 'com.android.application'
apply plugin: 'android-apt'
android {
    compileSdkVersion 23
    buildToolsVersion "24.0.2"

    defaultConfig {
        applicationId "com.itheima.testbutterknift"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'com.jakewharton:butterknife:8.4.0'
    apt 'com.jakewharton:butterknife-compiler:8.4.0'

}

2. 在Android Studio中点击File-->Settings-->Plugins-->Browse repositories,搜索Android ButterKnife Zelezny插件,安装成功以后重启Android Studio.
3. 在布局文件中添加控件的时候,所有需要在Activity/Fragment代码中进行控制的控件都要添加id属性
4. 在Activity/Fragment 代码中,将鼠标放在布局文件的引用上(即R.layout.activity_main中的activity_main上面),此时按快捷键Alt + Insert或鼠标右键选择Generate
5. 在弹出的菜单中选择Generate ButterKnife Injections,此时会再次弹出一个对话框
6. 新的对话框中点击confirm后直接生成控件的引用,代替findViewById
7. 如果需要处理控件的点击事件,可以选择对应控件的OnClick复选框.
8. 如果是ListView的Item视图,还可以选择左下角的Create ViewHolder复选框,生成ViewHolder静态类.
[Java] 纯文本查看 复制代码
package com.itheima.testbutterknift;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class MainActivity extends AppCompatActivity {
    @BindView(R.id.bt_1)
    Button bt1;
    @BindView(R.id.bt_2)
    Button bt2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

    }
    @OnClick({R.id.bt_1, R.id.bt_2})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.bt_1:
                break;
            case R.id.bt_2:
                break;
        }
    }
    public void loadView() {
        View view = View.inflate(this, R.layout.activity_main, null);
    }
    static class ViewHolder {
        @BindView(R.id.bt_1)
        Button bt1;
        @BindView(R.id.bt_2)
        Button bt2;

        ViewHolder(View view) {
            ButterKnife.bind(this, view);
        }
    }
}

Picasso显示网络图片
第一步:添加依赖
[Java] 纯文本查看 复制代码
compile 'com.squareup.picasso:picasso:2.5.2'

第二步:添加权限
[XML] 纯文本查看 复制代码
<uses-permission android:name="android.permission.INTERNET"/>
第三步:加载图片
[Java] 纯文本查看 复制代码
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ImageView iv = (ImageView) findViewById(R.id.iv);
        //联网加载图片
        Picasso.with(this).load("http://10.0.2.2:8080/zhbj/photos/images/46728356JBUO.jpg").into(iv);
    }
}
OkHttpUtils联网获取数据
[Java] 纯文本查看 复制代码
public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        OkHttpClient client=new OkHttpClient();
        String url = "http://10.0.2.2:8080/zhbj/categories.json";
        Request post_request = new Request.Builder()
                .url(url)// 指定请求的地址
                .build();
        client.newCall(post_request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // 请求失败的处理
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
// 请求成功的处理
                ResponseBody body = response.body();
                String string = body.string();// 把返回的结果转换为String类型
                // body.bytes();// 把返回的结果转换为byte数组
                // body.byteStream();// 把返回的结果转换为流
            }
        });
    }
}

因为原生OkHttp的使用比较复杂,而且请求后回调的方法是在子线程不能直接操作显示
添加依赖
[Java] 纯文本查看 复制代码
compile 'com.zhy:okhttputils:2.6.2'

使用:
[Java] 纯文本查看 复制代码
 public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //http://10.0.2.2:8080/zhbj/categories.json
        OkHttpUtils//联网工具类
                .get()//get请求方式
                .url("http://10.0.2.2:8080/zhbj/categories.json")//请求路径
                .build()//构建
                .execute(new StringCallback() {//执行请求    返回的是String类型的数据
                    @Override
                    public void onError(Call call, Exception e, int id) {
                    }
                    @Override
                    public void onResponse(String response, int id) {
                        Log.i(TAG,response);
                        Gson gson = new Gson();
                        CategoryBean categoryBean = gson.fromJson(response, CategoryBean.class);
                    }
                });
    }
}

TabPagerIndicator的使用
布局

编码

重写MyPagerAdapter的getPageTitle方法,作为ViewPagerIndiactor的标题

更换主题

2 个回复

倒序浏览
亲爱的小鲁哥哥,能不能给个完整的项目代码?我是一个自学者,写到下边不知道该咋写了,谢谢啦!
回复 使用道具 举报
多谢分享
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马