黑马程序员技术交流社区
标题: 【济南中心】Android课程同步笔记Day1:智慧北京 [打印本页]
作者: 小鲁哥哥 时间: 2017-4-8 22:33
标题: 【济南中心】Android课程同步笔记Day1:智慧北京
【济南中心】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的标题
更换主题
作者: Hosing 时间: 2017-7-11 17:55
亲爱的小鲁哥哥,能不能给个完整的项目代码?我是一个自学者,写到下边不知道该咋写了,谢谢啦!
作者: baby14 时间: 2018-11-26 08:02
多谢分享
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |