ViewPager+Fragment以及GridView的使用

今天项目中完成了一个界面,主要的框架式ViewPager加Fragment,在一个Fragment里边包含GridView显示网络图片
这里写图片描述
这里写图片描述
ViewPager+Fragment
首先需要一个继承自FragmentPagerAdapter的类,另外是需要一个继承自FragmentActivity的类,第一个是提供数据源,也就是控制Fragments,然后实现ViewPager的addOnPageChangeListener方法,并且在里边计算标签栏底部的引导线位移的位置。还有就是点击标签改变字体颜色,位移底部引导线。
上代码
顶部标签布局top_tab.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#ffffff"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/id_switch_tab_ll"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:baselineAligned="false"
        android:orientation="horizontal"
       >

        <LinearLayout
            android:id="@+id/id_tab_Detail_ll"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:clickable="true"
            android:gravity="center"
            android:orientation="horizontal"
           >

            <TextView
                android:id="@+id/id_detail_tv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="详情"
                android:textColor="#5aa828"
                android:textSize="15sp" />
        </LinearLayout>

        <View
            android:layout_width="2dp"
            android:layout_height="40dp"
            android:background="#e8e8e8" />

        <LinearLayout
            android:id="@+id/id_tab_photo_ll"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:orientation="horizontal"
            android:saveEnabled="false">

            <TextView
                android:id="@+id/id_photo_tv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="照片"
                android:textColor="#555555"
                android:textSize="15sp" />
        </LinearLayout>


    </LinearLayout>

    <ImageView
        android:id="@+id/id_tab_line_iv"
        android:layout_width="wrap_content"
        android:layout_height="2dp"
        android:background="@color/wave_text"
        android:padding="10dp"/>

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#ffffff"
        android:padding="10dp" />

</LinearLayout>

主界面布局activity_charge_detail.xml

 <include layout="@layout/top_tab" />

    <android.support.v4.view.ViewPager
        android:id="@+id/id_viewpager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp" />

定义一个继承自FragmentPagerAdapter的类,管理Fragment

public class ChargeDetailFragmentsAdapter extends FragmentPagerAdapter{
    private List<Fragment> mFragments;

    public ChargeDetailFragmentsAdapter(FragmentManager fm,List<Fragment> fragments) {
        super(fm);

        mFragments=fragments;
    }

    @Override
    public Fragment getItem(int arg0) {
        // TODO Auto-generated method stub
        return mFragments.get(arg0);
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return mFragments.size();
    }


}

定义两个Fragment,ChargeDetailFragment,ChargePhotosFragment,然后在主Activity里进行操作,主Activity继承FragmentActivity

public class ChargeDetailActivity extends FragmentActivity  {

    /**
     * ViewPager的当前选中页
     */
    private int currentIndex;
    /**
     * 屏幕的宽度
     */
    private int screenWidth;
    /**
     * Tab显示内容TextView
     */
    private TextView mTabDetailTv, mTabPhotoTv;
    /**
     * Tab的那个引导线
     */
    private ImageView mTabLineIv;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_charge_detail);
        setupViews();
        initTabLineWidth();
        //构造适配器
        List<Fragment> fragments = new ArrayList<Fragment>();
        fragments.add(new ChargeDetailFragment());
        fragments.add(new ChargePhotosFragment());

        ChargeDetailFragmentsAdapter adapter = new ChargeDetailFragmentsAdapter(getSupportFragmentManager(), fragments);

        //设定适配器
        final ViewPager vp = (ViewPager) findViewById(R.id.id_viewpager);
        vp.setAdapter(adapter);

        vp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            /**
             * state滑动中的状态 有三种状态(0,1,2) 1:正在滑动 2:滑动完毕 0:什么都没做。
             */
            @Override
            public void onPageScrollStateChanged(int state) {

            }

            /**
             * position :当前页面,及你点击滑动的页面 offset:当前页面偏移的百分比
             * offsetPixels:当前页面偏移的像素位置
             */
            @Override
            public void onPageScrolled(int position, float offset,
                                       int offsetPixels) {
                lineViewClick(position, offset);
            }

            @Override
            public void onPageSelected(int position) {
                textViewClick(position);
            }

        });

        findViewById(R.id.id_tab_Detail_ll).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                vp.setCurrentItem(0);
            }
        });
        findViewById(R.id.id_tab_photo_ll).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                vp.setCurrentItem(1);
            }
        });
    }

    //根绝viewpager变化,下划线改变位置
    private void lineViewClick(int pos, float offset) {
        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mTabLineIv
                .getLayoutParams();

        L.e("offset:", offset + "");
        /**
         * 利用currentIndex(当前所在页面)和position(下一个页面)以及offset来
         * 设置mTabLineIv的左边距 滑动场景:
         * 记2个页面,
         * 从左到右分别为0,1
         * 0->1;  1->0
         */

        if (currentIndex == 0 && pos == 0)// 0->1
        {
            lp.leftMargin = (int) (offset * (screenWidth * 1.0 / 2) + currentIndex
                    * (screenWidth / 2));

        } else if (currentIndex == 1 && pos == 0) // 1->0
        {
            lp.leftMargin = (int) (-(1 - offset)
                    * (screenWidth * 1.0 / 2) + currentIndex
                    * (screenWidth / 2));

        }
        mTabLineIv.setLayoutParams(lp);
    }

    //根据viewpager变化,标签改变位置
    private void textViewClick(int pos) {
        resetTextView();
        switch (pos) {
            case 0:
                mTabDetailTv.setTextColor(getResources().getColor(R.color.wave_text));
                break;
            case 1:
                mTabPhotoTv.setTextColor(getResources().getColor(R.color.wave_text));
                break;

        }
        currentIndex = pos;
    }


    private void setupViews() {
        mTabDetailTv = (TextView) this.findViewById(R.id.id_detail_tv);
        mTabPhotoTv = (TextView) this.findViewById(R.id.id_photo_tv);

        mTabLineIv = (ImageView) this.findViewById(R.id.id_tab_line_iv);
    }


    /**
     * 设置滑动条的宽度为屏幕的1/2(根据Tab的个数而定)
     */
    private void initTabLineWidth() {
        DisplayMetrics dpMetrics = new DisplayMetrics();
        getWindow().getWindowManager().getDefaultDisplay()
                .getMetrics(dpMetrics);
        screenWidth = dpMetrics.widthPixels;
        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mTabLineIv
                .getLayoutParams();
        lp.width = screenWidth / 2;
        mTabLineIv.setLayoutParams(lp);
    }

    /**
     * 重置颜色
     */
    private void resetTextView() {
        mTabDetailTv.setTextColor(getResources().getColor(R.color.txt_gray));

        mTabPhotoTv.setTextColor(getResources().getColor(R.color.txt_gray));

    }
}

这个功能主要注意的是计算底部直线位移位置。
GrideView使用
这个难点不多,不过一个比较纠结的事情是,作为子布局,好像不能使用LinearLayout,要不然行距比较大,使用RelativeLayout就正常了,现在还不知道为什么。。。
访问网络图片,使用的是Volley第三方库
使用GridView的Fragment代码

public class ChargePhotosFragment extends Fragment {


    public ChargePhotosFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
       View view = inflater.inflate(R.layout.fragment_charge_photos, container, false);
        GridView gridView = (GridView) view.findViewById(R.id.id_gridView);
        gridView.setAdapter(new ImageAdapter(getActivity()));
        return view;
    }

    private class ImageAdapter extends BaseAdapter {
        private Context mContext;

        public ImageAdapter(Context context) {
            this.mContext = context;
        }

        @Override
        public int getCount() {
            return 6;
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            if (convertView == null) {
                convertView = LayoutInflater.from(getActivity()).inflate(R.layout.gridview_item, null);

            }
            final ImageView imageView = ViewHolder.get(convertView, R.id.imageView);


            RequestQueue mQueue = Volley.newRequestQueue(mContext);

            ImageRequest imageRequest = new ImageRequest(
                    "http://article.fd.zol-img.com.cn/t_s640x2000/g5/M00/04/0C/ChMkJlZzfxiIAmYDAAtzF_G-oB0AAGSPAIJtIMAC3Mv324.jpg",
                    new Response.Listener<Bitmap>() {
                        @Override
                        public void onResponse(Bitmap response) {
                            imageView.setImageBitmap(response);
                        }
                    }, 0,0, Bitmap.Config.RGB_565, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    imageView.setImageBitmap(null);
                }
            });
            mQueue.add(imageRequest);

            return convertView;
        }


    }


}

fragment_charge_photos.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:background="#f2f2f2"
    android:orientation="vertical">

    <GridView
        android:id="@+id/id_gridView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
       android:horizontalSpacing="10dp"
        android:numColumns="auto_fit"
        android:columnWidth="120dp"
        android:stretchMode="columnWidth"
        android:verticalSpacing="10dp" />

</LinearLayout>

gridview_item.xml
外部布局使用RelativeLayout 好像没什么问题,LinearLayout貌似有问题,不知道是程序问题还是其他问题。。。

<?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="wrap_content">
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        />
</RelativeLayout>

在另外的测试机上发现还是有问题,现在两种解决方法,一个是宽高写死,不用wrap_content,另一个就是这样

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/imageView"
     android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:scaleType="centerCrop"
    >

</ImageView>

先记下来吧,以后有时间再研究

另外提供一个类,因为ListView或者GridView设置Adapter的方法都类似,一般都是定义一个ViewHolder,为了简化,定义一个工具类,当然,这个也是网上找到的

public class ViewHolder {
    public static  <T extends View> T get(View view, int id) {
        SparseArray<View> viewHolder = (SparseArray<View>) view.getTag();
        if (viewHolder == null) { 
            viewHolder = new SparseArray<View>(); 
            view.setTag(viewHolder); 
        } 
        View childView = viewHolder.get(id); 
        if (childView == null) { 
            childView = view.findViewById(id); 
            viewHolder.put(id, childView); 
        } 
        return (T) childView; 
    } 
} 

GridView的一些特殊属性:

1.android:numColumns=”auto_fit” //GridView的列数设置为自动

2.android:columnWidth=”90dp ” //每列的宽度,也就是Item的宽度

3.android:stretchMode=”columnWidth”//缩放与列宽大小同步

4.android:verticalSpacing=”10dp” //两行之间的边距

5.android:horizontalSpacing=”10dp” //两列之间的边距

6.android:cacheColorHint=”#00000000” //去除拖动时默认的黑色背景

7.android:listSelector=”#00000000” //去除选中时的黄色底色

8.android:scrollbars=”none” //隐藏GridView的滚动条

9.android:fadeScrollbars=”true” //设置为true就可以实现滚动条的自动隐藏和显示

10.android:fastScrollEnabled=”true” //GridView出现快速滚动的按钮(至少滚动4页才会显示)

11.android:fadingEdge=”none” //GridView衰落(褪去)边缘颜色为空,缺省值是vertical。(可以理解为上下边缘的提示色)

12.android:fadingEdgeLength=”10dip” //定义的衰落(褪去)边缘的长度

13.android:stackFromBottom=”true” //设置为true时,你做好的列表就会显示你列表的最下面

14.android:transcriptMode=”alwaysScroll” //当你动态添加数据时,列表将自动往下滚动最新的条目可以自动滚动到可视范围内

15.android:drawSelectorOnTop=”false” //点击某条记录不放,颜色会在记录的后面成为背景色,内容的文字可见(缺省为false)

源码
源码下载

参考博客
Android ViewPager和Fragment实现顶部导航界面滑动效果
Android GridView属性集合
使用Volley加载网络图片
GridView组件的使用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值