在activity中我们一般使用这三个方法 initUI() initListener() initData().
//initView()
Button bt=(Button) findViewById(R.id.bt);
//initListener 这个监听器 一般用于监听其他的事件,不用于监听按钮
bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
}
});
//initData();
bt.setText("xxxxx");
//processClick();
//这个类主要用于接收 控件的监听器 比如按钮之内的,用你的activity去实现监听器
//后就用这个方法去实现方法。
项目的一些规范用法:
一般我们在写项目的时候,会去定义一个BaseActivity。用这个Activity作为抽象基类,
然后暴露一些抽象方法,这样你在要写的Activity去继承这个基类的Activity,这样你只需要去重写他的抽象方法就可以了。
我们一般会写一个基类专门的包 com.xxx.xxx.base
package com.chen.textttt.base;
import android.app.Activity;
import android.os.Bundle;
public abstract class BaseActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initView();
initListener();
initData();
}
public abstract void initView();
public abstract void initListener();
public abstract void initData();
//这个步骤可以避免强转。直接调用这个方法即可
public <T> T findView(int id) {
@SuppressWarnings("unchecked")
T view = (T) findViewById(id);
return view;
}
}
然后我们会使用activity去继承这个类 然后实现方法,这样的好处在于你就不需要在你的Activity里面写很长的方法。在onCreate里面。
这里注意一点:就是我们的setContenView();方法要写在initView()里面,不写在BaseActivity里面的原因就是因为,每一个Acitivity都应该又自己决定自己的布局。
public class MainActivity extends BaseActivity {
private Button bt;
public void initView() {
setContentView(R.layout.activity_main);
bt = (Button) findViewById(R.id.bt);
}
public void initListener() {
bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
}
});
}
public void initData() {
bt.setText("xxxxx");
}
}
这里我们一般不用initListener 去实现监听方法。一般用是这样去实现的。
我们先在BaseActivity里面去实现点击事件的监听。
然后去实现onclick方法。因为我们的点击事件的方法是给其他继承它的类实现的。
所以我们需要提供一个抽象方法,然后在点击的时候实现这个方法。这样继承baseactivcity的Activity只需要实现这个方法就可以实现点击事件了。
public class MainActivity extends BaseActivity {
private Button bt;
public void initView() {
setContentView(R.layout.activity_main);
bt = (Button) findViewById(R.id.bt);
}
public void initListener() {
//这里就是因为你继承了BaseActivity所以相当于已经实现了 这个监听器。所以直接传递当前类的对象即可
bt.setOnClickListener(this);
}
public void initData() {
bt.setText("xxxxx");
}
@Override
public void progressClick(View v) {
//这里就是处理当前监听的事件的内容
switch (v.getId()) {
case value:
break;
default:
break;
}
}
}
public abstract class BaseActivity extends Activity implements OnClickListener {
public abstract void processClick(View v);
@Override
public void onClick(View v) {
progressClick(v);
}
}
————————————————————————————————————
ViewPager 的介绍:
中间是一个ViewPager:由于是扩展包中的类所以我们在xml中定义的时候需要全包名
ViewPager是android扩展包v4包中的类,这个类可以让用户左右切换当前的view。
1)ViewPager类直接继承了ViewGroup类(相当于Layout),所有它是一个容器类,可以在其中添加其他的view类。
2)ViewPager类需要一个PagerAdapter适配器类给它提供数据。
3)ViewPager经常和Fragment一起使用,并且提供了专门的FragmentPagerAdapter和FragmentStatePagerAdapter类供Fragment中的ViewPager使用。
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</android.support.v4.view.ViewPager>
小知识:如何查看扩展包中的类的源码
首先找到你的sdk位置,然后找到extras,然后找到android,然后找到support\v4\src
复制地址C:\Users\xx\AppData\Local\Android\sdk\extras\android\support\v4\src
然后在libs里面创建一个文件,名字为: android-support-v4.jar.properties
然后在这个文件里面写入
src=C:\\Users\\CC\\AppData\\Local\\Android\\sdk\\extras\\android\\support\\v4\\src
这里注意需要把斜杠写成转义字符。然后重启即可。
你就可以去扩展包里面找你想要查看的类 双击即可。
————————————————————————
选项卡栏的布局设计:
这里绿色和蓝色是线性布局 最外面是相对布局。
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="#292B28" >
<View
android:layout_width="60dp"
android:layout_height="4dp"
android:layout_alignParentBottom="true"
android:background="#CE0000" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/img_conversation" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="会话"
android:textColor="#FFFFFF"
android:textSize="14sp" />
</LinearLayout>
这里只是一个例子,我们需要注意这个红线我们只能在 代码中动态的去设置他的宽。
————————————————————————————————
定义Fragment基类&FragmentPagerAdapter:
我们先在initView()中找到ViewPage控件。
由于我们的ViewPage控件控制的是三个Fragment所以,我们和activity一样,先定义一个基类的Fragment.
public abstract class BaseFragment extends Fragment implements OnClickListener{
//返回一个view对象 这个对象会作为fragment显示的内容
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//注意这里我们不能直接去实现fragment显示的内容,因为这是一个基类
//所以我们需要暴露一个抽象方法出去
return initView(inflater, container, savedInstanceState);
}
//跟Fragment关联的Activity被创建的时候调用
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//因为我们需要在activity创建的时候才去调用这两个方法
initListener();
initData();
}
public abstract View initView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState);
public abstract void initListener();
public abstract void initData();
public abstract void processClick(View v);
@Override
public void onClick(View v) {
processClick(v);
}
}
ViewPage要显示内容,我们就需要给他设置子节点。那么我们需要三个子节点。
由于ViewPage需要显示数据 他和ListView一样 需要一个Adapter.
pageAdapter:给viewpage设置一个View对象不适合Fragment。
所以我们一般使用FragmentPageAdapter: 这个就是给viewpage设置一个Fragment.
public class MainAdapter extends FragmentPagerAdapter {
List<Fragment> fragments;
public MainAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
}
————————————————————————————————————
ViewPager显示三个Fragment:
首先我们需要创建三个Fragment继承我们前面写的BaseFragment;
public class ConversionFragment extends BaseFragment {
@Override
public View initView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_conversation, null);
return view;
}
@Override
public void initListener() {
}
@Override
public void initData() {
}
@Override
public void processClick(View v) {
}
}
创建好三个Fragment 之后我们要去定义三个布局文件来给Fragment作为显示。
设置好之后我们就可以在activity里面给ViewPage设置他的adapter
public class MainActivity extends BaseActivity {
private ViewPager viewPager;
private List<Fragment> fragments;
public void initView() {
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.viewPager);
}
public void initListener() {
}
public void initData() {
fragments = new ArrayList<Fragment>();
ConversionFragment fragment1 = new ConversionFragment();
GroupFragment fragment2 = new GroupFragment();
SearchFragment fragment3 = new SearchFragment();
fragments.add(fragment1);
fragments.add(fragment2);
fragments.add(fragment3);
//这里由于我们使用的Fragment是V4包下面的所以,我们要获取FragmentManager
//就需要我们的BaseActivity继承FragmentActivity才可以。
//然后通过getSupportFragmentManager()去获得FragmentManager
MainAdapter adapter = new MainAdapter(getSupportFragmentManager(), fragments);
viewPager.setAdapter(adapter);
}
@Override
public void progressClick(View v) {
}
}
这里由于我们使用的Fragment是V4包下面的所以,我们要获取FragmentManager
就需要我们的BaseActivity继承FragmentActivity才可以。
然后通过getSupportFragmentManager()去获得FragmentManager
__________________________________________________________
改变选项卡的文字大小和颜色:
我们需要修改这些属性,需要在viewPage改变的时候去修改,所以我们先给他一个监听器。
addOnPageChangeListener();
将这个方法写在 initListener()里面,这是因为只有这一个activity才使用它,所以不需要再BaseActivity里面定义方法。
public void initListener() {
viewPager.addOnPageChangeListener(new OnPageChangeListener() {
//当界面切换完成的时候调用。返回当前界面的索引。索引是从0开始
@Override
public void onPageSelected(int position) {
textColorAndScale();
}
//当你移动的时候就可以调用这个方法
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
}
//当用户开始拖动的时候调用
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
protected void textColorAndScale() {
int item = viewPager.getCurrentItem();
tv_conversation.setTextColor(item == 0 ? Color.WHITE : Color.BLACK);
tv_group.setTextColor(item == 1 ? Color.WHITE : Color.BLACK);
tv_search.setTextColor(item == 2 ? Color.WHITE : Color.BLACK);
switch (item) {
case 0:
ObjectAnimator.ofFloat(tv_conversation, "scaleY", 1, 1.2f).start();
ObjectAnimator.ofFloat(tv_conversation, "scaleX", 1, 1.2f).start();
break;
case 1:
ObjectAnimator.ofFloat(tv_group, "scaleY", 1, 1.2f).start();
ObjectAnimator.ofFloat(tv_group, "scaleX", 1, 1.2f).start();
break;
case 2:
ObjectAnimator.ofFloat(tv_search, "scaleY", 1, 1.2f).start();
ObjectAnimator.ofFloat(tv_search, "scaleX", 1, 1.2f).start();
break;
}
}
点击选项卡切换:
viewPage.的监听器里面 的:
onPageSelected(int position)方法不仅在界面切换时会调用,在你的索引改变的时候也会调用。
所以我们只需要在点击三个绿色布局的时候调用监听器,然后点击事件的时候去设置
viewPage的当前界面的索引即可
@Override
public void progressClick(View v) {
switch (v.getId()) {
case R.id.ll_tab_conversation:
viewPager.setCurrentItem(0);
break;
case R.id.ll_tab_group:
viewPager.setCurrentItem(1);
break;
case R.id.ll_tab_search:
viewPager.setCurrentItem(2);
break;
}
——————————————————————————————————————
选项卡的红线移动;
我们先在initView()里面找到控件。
然后在 initData();里面去写一个方法setIndicationline();
private void setIndicationline() {
int width = getWindowManager().getDefaultDisplay().getWidth();//通过这API获取屏幕宽度
tab_indication_red.getLayoutParams().width=width/3;//通过这个API设置控件的宽度
}
然后我们要去动态的改变红线和我们的移动屏幕一起变换。
//viewpager界面切换时会触发
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
//切换完成后调用,传入的参数是切换后的界面的索引
@Override
public void onPageSelected(int position) {
textLightAndScale();
}
//滑动过程不断调用
//如果滑动过程中出现两个界面,position是前一个的索引
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
System.out.println(positionOffsetPixels);
//计算红线位移的距离
int distance = positionOffsetPixels / 3;
//持续时间为0,立刻生效,因为红线的移动需要与用户滑动同步
ViewPropertyAnimator.animate(v_indicate_line).translationX(distance + position * v_indicate_line.getWidth()).setDuration(0);
}
@Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
}
});
onPageSelected和onPageScrolled,第一个方法中的position和第二个position方法
不一样。
第一个方法中position是当你的界面移动完成的时候才会变。
第二个方法中的position是当你的界面只要你一移动就会变,根据你的移动方向变,
比如你向右移动那么你一移动,就会变成你移动方向界面的索引。
这个方法ViewPropertyAnimator.animate(v_indicate_line).translationX(distance + position * v_indicate_line.getWidth()).setDuration(0);
是在nineoldandroids-2.4.0.jar 库文件中的方法。
这个方法是可以兼容9以下的API,所以我们可以使用这个方法,
onPageScrolled()这个方法中的positionOffsetPixels这个参数的意思就是动态获取你的
移动的像素,当移动结束后就会变成0,你向右移动会增大,向左移会变小。
只要你移动就会获取你的像素。
我们为了给红线动态的和屏幕移动一起变化,所以我们需要用到这个参数。
distance=positionOffsetPixels/3;
因为positionOffsetPixels就是获取你一个界面移动到另外一个界面的像素。
相当于你手机屏幕的宽度。
当时positionOffsetPixels这个参数 停止移动后会变成0,也就是说你移动过后红线还是会变成他的初始值。
所以我们应该动态的给红线添加初始值。
distance+ position * 控件id.getwidth();
因为你每次移动相当于下一个界面的索引*控件的宽度作为初始值。
但是有一个小问题,当你移动到最右边的时候。你向左移,但是distance 还是正数。
按道理下一个初始值应该还是会变大,但是没有变大。
原因就是因为position只要你一移动 ,它就会变,也就是说你向左一移动,马上就会变小。
所以才会导致我们的红线还能变回去。