ViewPager动态添加、删除Fragment,且提供红色小圆球指示当前位置

简介: 简单的说,代码要实现的是类似于现在通用新闻客户端头部的新闻图片展示。现在的新闻客户端顶部一般放有图片展示区,假设有5张图片,用户可以左右侧滑翻阅,同时提供一行5个红色小圆球(红色小圆球的个数等于图片数目),假设当用户翻到第3张图片时候,红色小圆球也相应的指示到第3位置。

简单的说,代码要实现的是类似于现在通用新闻客户端头部的新闻图片展示。现在的新闻客户端顶部一般放有图片展示区,假设有5张图片,用户可以左右侧滑翻阅,同时提供一行5个红色小圆球(红色小圆球的个数等于图片数目),假设当用户翻到第3张图片时候,红色小圆球也相应的指示到第3位置。自然,图片标题也要设置成相对应于图片的内容。

代码功能简要说明:

(1)一个ViewPager,每个page加载不同的Fragment,整个ViewPager中的Fragment可以动态删除和添加。

(2)当ViewPager在左右侧滑时候,下方的提示和红色小圆球也相应的滑动指示当前的Page在所有Page中位置和标题。


MainActivity.java

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;

public class MainActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
  
        Fragment newFragment =new  ViewPagerWithCircleIndicatorView();
        FragmentTransaction transaction =getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.fragment,newFragment);
        transaction.commit();

    }
}


MainActivity.java需要的activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
   
    <FrameLayout 
   		android:id="@+id/fragment"  
        android:layout_width="match_parent"
    	android:layout_height="match_parent">	
    </FrameLayout>
    
    
 </LinearLayout>



ViewPagerWithCircleIndicatorView.java 该类是重点。实现ViewPager和红色小圆球指示器。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;

import zhangphil.libs.view.CircleIndicatorView;

import com.example.viewpager_fragment.R;

import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

/**
 * @author Phil
 *
 */
public class ViewPagerWithCircleIndicatorView extends Fragment {

	private MyFragmentPagerAdapter mPagerAdapter;
	private ViewPager mViewPager;

	private Handler handler;
	private final int MESSAGE_WHAT_CHANGED = 100;

	private ArrayList<HashMap<String, Object>> mArrayList = null;
	private final String FRAGMENT = "fragment_tag";

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setHasOptionsMenu(true);
		mArrayList = new ArrayList<HashMap<String, Object>>();
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View mView = inflater.inflate(R.layout.viewpager_fragment, null);

		mViewPager = (ViewPager) mView.findViewById(R.id.viewpager);

		mPagerAdapter = new MyFragmentPagerAdapter(getFragmentManager());
		mViewPager.setAdapter(mPagerAdapter);
		mViewPager
				.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

					@Override
					public void onPageSelected(int pos) {
						set(pos);
					}

					@Override
					public void onPageScrolled(int arg0, float arg1, int arg2) {

					}

					@Override
					public void onPageScrollStateChanged(int arg0) {

					}
				});

		final TextView circleIndicatorView_TextView=(TextView)mView.findViewById(R.id.circleIndicatorView_TextView);
		final CircleIndicatorView mCircleIndicatorView = (CircleIndicatorView) mView
				.findViewById(R.id.circleIndicatorView);
		handler = new Handler() {
			public void handleMessage(Message msg) {
				super.handleMessage(msg);
				switch (msg.what) {
				case MESSAGE_WHAT_CHANGED:
					mCircleIndicatorView.setCircleCount(mPagerAdapter
							.getCount());
					mCircleIndicatorView.setCircleSelectedPosition(mViewPager
							.getCurrentItem());
					mCircleIndicatorView.setSelectedCircleRadius(7);
					mCircleIndicatorView.setCircleUnSelectedColor(Color.BLUE);
					mCircleIndicatorView.drawCircleView();
					
					TestFragment tf=(TestFragment) mArrayList.get(mViewPager.getCurrentItem()).get(FRAGMENT);
					String title=tf.getTitle();					
					circleIndicatorView_TextView.setText(title);
					
					break;
				}
			};
		};

		
	
		// 初始化,在此,可选
		initialization();

		// 初始化选择第一项
		if (mPagerAdapter.getCount() > 0) {
			set(0);
		}

		return mView;
	}

	private void initialization() {
		// 在这里做初始化工作,如果有指定的Fragment,在此预装载

		// Fragment fragment;//创建一个Fragment
		// View view;//一个下方选项卡的View
		// add(fragment, view);
	}

	private void add(Fragment fragment) {

		HashMap<String, Object> map = new HashMap<String, Object>();

		Bundle args = new Bundle();
		fragment.setArguments(args);
		map.put(FRAGMENT, fragment);
		
		mArrayList.add(map);
	}


	private final void delete(int pos) {
		mArrayList.remove(pos);
		mPagerAdapter.notifyDataSetChanged();
	}

	private void set(int pos) {
		mViewPager.setCurrentItem(pos, true);
		handler.sendEmptyMessage(MESSAGE_WHAT_CHANGED);
	}

	private class MyFragmentPagerAdapter extends FragmentStatePagerAdapter {

		public MyFragmentPagerAdapter(FragmentManager fm) {
			super(fm);
		}

		@Override
		public Fragment getItem(int pos) {
			return (Fragment) mArrayList.get(pos).get(FRAGMENT);
		}

		@Override
		public int getItemPosition(Object object) {
			return FragmentPagerAdapter.POSITION_NONE;
		}

		@Override
		public int getCount() {
			return mArrayList.size();
		}

		@Override
		public void notifyDataSetChanged() {
			super.notifyDataSetChanged();
			handler.sendEmptyMessage(MESSAGE_WHAT_CHANGED);
		}

	}

	private Fragment loadFragment() {
		return new TestFragment();
	}

	protected void onActionAdd() {
		add(loadFragment());
		mPagerAdapter.notifyDataSetChanged();
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		switch (item.getItemId()) {
		case R.id.action_add:
			onActionAdd();
			break;

		case R.id.action_dele:
			delete(mViewPager.getCurrentItem());
			set(mViewPager.getCurrentItem());
			break;

		default:
			break;
		}

		return super.onOptionsItemSelected(item);
	}

	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		inflater.inflate(R.menu.main, menu);
	}
	

	//
	// 仅仅用于测试的Fragment,在ViewPager中加载
	//
	public static class TestFragment extends Fragment {

		private final	String title = new Random().nextInt(20)+"";

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {

			TextView tv = new TextView(getActivity());

			String str = "Fragment : "+title+"\n";
			for (int i = 0; i < 500; i++)
				str = str + i + "--";

			tv.setTextColor(Color.LTGRAY);
			tv.setText(str);

			return tv;
		}
		
		public	String	getTitle(){
			return	title;
		}
	}
}



红色小圆球的绘制类:CircleIndicatorView.java


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class CircleIndicatorView extends View { 
	
    public CircleIndicatorView(Context context, AttributeSet attrs){   
    	       super(context, attrs);  
    }
    
    private	int	gap=20;//各个横向排列的小球间距
	public	void	setCirlceGap(int gap){
	    	this.gap=padding;
	}
	public	int	getCirlceGap(){
	    	return	gap;
	}
    
    private	int	padding=20;
    public	void	setPadding(int padding){
    	this.padding=padding;
    }
    public	int	getPadding(){
    	return	padding;
    }
    
    private	int	circle_normal_radius=5; //普通小球半径
    public	void	setNormalCircleRadius(int radius){
    	this.circle_normal_radius=radius;
    }
    public	int	getNormalCircleRadius(){
    	return	circle_normal_radius;
    }
    
    private	int	circle_selected_radius=5; //被选择的小球半径
    public	void setSelectedCircleRadius(int radius){
    	this.circle_selected_radius=radius;
    } 
    public	int	getSelectedCircleRadius(){
    	return	circle_selected_radius;
    }
    
    private	int	count=0;
    public	void	setCircleCount(int count){
    	this.count=count;
    }
    public	int	getCircleCount(){
    	return	count;
    }

    private	int	pos=0;
    public	void	setCircleSelectedPosition(int pos){
    	this.pos=pos;
    }
    public	int	getCircleSelectedPosition(){
    	return	pos;
    }
    
    public	void	drawCircleView(){
    	this.invalidate();
    }
    
    private	int	circleSelectedColor=Color.RED;
    public	void	setCircleSelectedColor(int color){
    	circleSelectedColor=color;
    }
    public	int	getCircleSelectedColor(){
    	return	circleSelectedColor;
    }
    
    private	int	circleUnSelectedColor=Color.LTGRAY;
    public	void	setCircleUnSelectedColor(int color){
    	circleUnSelectedColor=color;
    }
    public	int	getCircleUnSelectedColor(){
    	return	circleUnSelectedColor;
    }

    
    @Override  
    protected void onDraw(Canvas canvas) {  
        super.onDraw(canvas); 
        
        Paint p = new Paint();  
        p.setAntiAlias(true);
        
        int w=this.getWidth();
        int h=this.getHeight();
        
        //因为是自右往左绘制小圆圈,需要转化pos的位置。
      int translate_pos=getCircleCount()-getCircleSelectedPosition()-1;
       
      //如果居中绘制则使用start_x,但需要依次递加x坐标轴位置值。
      //int start_x=(w-(CIRCLE_GAP*(getCircleCount()-1)))/2;
        
        for(int i=0;i<getCircleCount();i++){
        	int r=getNormalCircleRadius();
        	
        	if(i==translate_pos){
        		r=getSelectedCircleRadius();
        		p.setColor(getCircleSelectedColor());
        	}
        	else{
        		r=getNormalCircleRadius();
        		p.setColor(getCircleUnSelectedColor()); 
        	}
        	
        	//自右向左绘制。从最右边往左边绘制小球
        	//如果从该自定制的View左边绘制,直接将 x=0即可。
        	canvas.drawCircle(w-i*getCirlceGap()-getPadding(), h/2, r, p);
        }
    } 
}  



ViewPagerWithCircleIndicatorView.java需要的viewpager_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >
    
    
   <FrameLayout 
    android:layout_weight="1"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="30dip"
        android:orientation="horizontal"
        android:layout_gravity="bottom" >

        <TextView
            android:id="@+id/circleIndicatorView_TextView"
            android:layout_width="0dip"
            android:layout_height="match_parent"
            android:gravity="left"
            android:textColor="#FF0000"
            android:layout_weight="0.618"
            android:singleLine="true"
            android:text="abcdefghijklmnopqrstuvwxyz01234567890123456789" />
        
        <zhangphil.libs.view.CircleIndicatorView
            android:id="@+id/circleIndicatorView"
            android:layout_width="0dip"
            android:layout_height="match_parent"
            android:layout_weight="0.382"/>
        
    </LinearLayout>

</FrameLayout>
 
</LinearLayout>




系统的添加、删除菜单需要。res\menu目录下,main.xml,菜单布局文件:

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/action_add"
        android:orderInCategory="100"
        android:showAsAction="never"
        android:title="添加"/>

    <item
        android:id="@+id/action_dele"
        android:orderInCategory="100"
        android:showAsAction="never"
        android:title="删除"/>
</menu>


效果图:




相关文章
ViewPager 显示 两侧的View,各显示一点
ViewPager 显示 两侧的View,各显示一点
ViewPager 显示 两侧的View,各显示一点
|
iOS开发
iOS开发 - touchBegan事件判断点击的位置在View上还是在View的子View上
iOS开发 - touchBegan事件判断点击的位置在View上还是在View的子View上
238 0
iOS开发 - touchBegan事件判断点击的位置在View上还是在View的子View上
ViewPager如何区分自动切换和手势滑动切换
ViewPager是一个很常见的组件,不仅支持收拾滑动切换页面,我们还可以通过`viewPager.setCurrentItem(index)`来切换到指定的页面,那么他们如何区分呢? 我们知道ViewPager可以添加`ViewPager.OnPageChangeListener`监听器,可以监听切换的状态。通过观察`ViewPager.OnPageChangeListener#onPageScrollStateChanged(int state)`方法中state的输出,发现了手势切换和自动切换的规律。
|
C++
Qt动态添加控件并设置大小位置等属性
Qt动态添加控件并设置大小位置等属性
891 0
|
容器
使用Fragmentation,start跳转到嵌套viewpager页面出现返回键重写失效原因。
最近在写项目时,采用的是单Activity+多Fragment的架构,用的Fragmentation的库。我的主页面是一个BootomFragment的抽象类(当然它还有一个管理类),其又继承自最大的LatteDelegate,LatteDelegate又继承自Fragment并实现Fragmentation库的接口,当然,当然这只是其中一部分,所以简略的讲了一下,大概知道层次就行。
75 0
使用Fragmentation,start跳转到嵌套viewpager页面出现返回键重写失效原因。
BottomNavigationView使用,配合ViewPager、修改图标大小、去掉文字等
BottomNavigationView使用,配合ViewPager、修改图标大小、去掉文字等
588 0
BottomNavigationView使用,配合ViewPager、修改图标大小、去掉文字等
fragment嵌套viewpager不显示
fragment嵌套viewpager不显示
162 0
ExpandableListView getChildView 不执行,不显示子列表
原因很简单:   在 GroupView 里面不要加入 button 等可点击空间,否则 和 点击 Groupview 展开相冲突。 去掉就好了getGroupView
1751 0