自定义学习Scrollview嵌套多种控件

说一下为什么要写自定义类,那是因为它可以减少使用的布局,节省很多.xml文件,管理方便 ,只用一个类就可以完成多个控件的操作

这里写图片描述


自定义ScroollView 简单嵌套了一个自定义广告轮播和测量好高度的ListView,还有商品菜单展示

效果图:

这里写图片描述


代码

MainActivity.java

public class MainActivity extends Activity {
    private List<String> list = new ArrayList<>();
    private MyAdapter    adapter;
    private MyScrollview mSC;
    private View         topView;
    private LinearLayout mLin;

    //private ImageView img;
    private AdverView adver;

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

    private void initView() {
        mSC = (MyScrollview) findViewById(R.id.mSC);
        topView = View.inflate(this, R.layout.top_view, null);
        mLin = (LinearLayout) topView.findViewById(R.id.mLin);
        adver = new AdverView(this);
        //广告轮播
        mLin.addView(adver.getView());
        mSC.setTop(topView);

        adapter = new MyAdapter(this, list);
        //设置Listview数据
        mSC.setAdapter(adapter);

    }

    private void initList() {
        for (int i = 0; i < 50; i++) {
            list.add("第" + i + "条数据");
        }
    }
}

MyScrollview.java

/**
 * 自定义的scrollview
 * */
public class MyScrollview extends ScrollView{
    private LinearLayout linear;
    private LinearLayout topView;
    private ListView lv;
    public MyScrollview(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }
    private void initView() {
        //动态设置控件参数
        linear=new LinearLayout(getContext());
        //获取控件的参数:控件在父容器中所要占的位置的参数
        RelativeLayout.LayoutParams lp=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
        linear.setLayoutParams(lp);
        //动态指定线方向
        linear.setOrientation(LinearLayout.VERTICAL);
        //将linear添加到自定义srcollview中
        addView(linear);
        //!!!!!!开始往linear添加内容
        topView=new LinearLayout(getContext());
        //给topView设置属性,设置其在父容器linear中所占的位置
        topView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
        linear.addView(topView);

        lv=new ListView(getContext());
        LinearLayout.LayoutParams lvlp=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
        lvlp.topMargin=20; //上边距20
        lv.setLayoutParams(lvlp);
        //取消焦点,在最顶部显示
        lv.setFocusable(false);
        linear.addView(lv);
    }
    //给lv设置适配器的方法
    public void setAdapter(MyAdapter adapter){
        lv.setAdapter(adapter);
        measureLv();
    }
    public void setTop(View v){
        v.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
        topView.addView(v);
    }

    /**
     * 测量 解决Scrollview嵌套listview的问题
     */
    private void measureLv(){
        ListAdapter adapter=lv.getAdapter();
        int height=0;
        for(int i=0;i<adapter.getCount();i++){
            View item=adapter.getView(i, null, null);
            item.measure(0, 0);
            height+=item.getMeasuredHeight();
        }
        height=height+lv.getDividerHeight()*(adapter.getCount()-1)+lv.getPaddingTop()+lv.getPaddingBottom();
        LinearLayout.LayoutParams lp=(android.widget.LinearLayout.LayoutParams) lv.getLayoutParams();
        lp.height=height;
        lv.setLayoutParams(lp);
        requestLayout();
    }
}

MyAdapter.java

/***
 * ListView适配器
 */
public class MyAdapter extends BaseAdapter{
    private List<String> list;
    private Context ctx;
    public MyAdapter(Context ctx,List<String> list) {
        this.ctx=ctx;
        this.list=list;
    }
    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return list.size();
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return list.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if(convertView==null){
            holder=new ViewHolder();
            convertView=View.inflate(ctx, R.layout.item_lv, null);
            holder.tv=(TextView) convertView.findViewById(R.id.tv);
            convertView.setTag(holder);
        }else{
            holder=(ViewHolder) convertView.getTag();
        }
        holder.tv.setText(list.get(position));
        return convertView;
    }
    private class ViewHolder{
        private TextView tv;
    }
}

AdverView.java

/*
 * 广告轮播类
 * */
public class AdverView implements OnPageChangeListener {
    private ViewPager vp;
    private Context ctx;

    private RelativeLayout relat;
    private List<View> list=new ArrayList<View>();//vp适配器的数据源
    private int []arr={R.mipmap.introduce_01,R.mipmap.introduce_02,R.mipmap.introduce_03,R.mipmap.introduce_04};
    private boolean touchFlag=false;//触摸锁
    private boolean threadFlag=true;//控制发送消息的锁
    View [] views=new View[arr.length];
    private VpAdapter adapter;
    private int index=0;
    public AdverView(Context ctx) {
        this.ctx=ctx;
        initList();
        initView();
        TimeThread thread=new TimeThread();
        thread.start();
    }
    //获取当前view的方法
    public View getView(){
        return relat;
    }
    private void initView() {
        relat=new RelativeLayout(ctx);
        vp=new ViewPager(ctx);
        adapter=new VpAdapter();
        vp.setAdapter(adapter);
        vp.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
        relat.addView(vp);
        vp.setOnPageChangeListener(this);
    }
    //初始化数据源
    private void initList() {
        for(int i=0;i<arr.length;i++){
            ImageView img=new ImageView(ctx);
            img.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            img.setScaleType(ScaleType.FIT_XY);
            img.setImageResource(arr[i]);
            list.add(img);
            views[i]=img;
        }
    }
    private Handler hand=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            super.handleMessage(msg);
            if(msg.what==0){
                if(touchFlag){
                    return;
                }
                if(!threadFlag){
                    return;
                }
                index++;
                vp.setCurrentItem(index);
            }
        }
    };
    private class VpAdapter extends PagerAdapter{

        @Override
        public int getCount() {
            return Integer.MAX_VALUE;
        }

        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0==arg1;
        }
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            ((ViewPager)container).removeView(list.get(position%views.length));
        }
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            // TODO Auto-generated method stub
            ((ViewPager)container).addView(list.get(position%views.length));
            //将要显示的View返回出去
            return list.get(position%views.length);
        }
    }
    @Override
    public void onPageScrollStateChanged(int arg0) {
        if(arg0==ViewPager.SCROLL_STATE_IDLE){
            touchFlag=false;//人为滑动结束之后改为false,继续启动
        }else{
            touchFlag=true;//人为滑动时,停止自动轮播
        }
    }
    @Override
    public void onPageScrolled(int arg0, float arg1, int arg2) {

    }
    @Override
    public void onPageSelected(int arg0) {
        //
        index=arg0;
    }
    private class TimeThread extends Thread{
        @Override
        public void run() {
            while(threadFlag){
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                hand.sendEmptyMessage(0);
            }
        }
    }
}

该项目已经上传到github

猜你喜欢

转载自blog.csdn.net/m0_37711172/article/details/79972862