HorizontalView实现的tabView

近日由于项目需要自己写了一个tabView,暂时支持两种模式,拓展重写的可行性还是比较好,主要思路很简单,实现也不复杂,代码比较简单,下面稍微记录一下。不正指出希望各位路过的大牛指正一下。

效果图:

上面图片上下两个tabView是同一个用horizontalview重写的组件,只是初始形态不同,上面设置了可以滚动,下面禁用滚动,上面的tab点击的时候如果能滚动到中间则会尽量滚动到中间显示。

废话不多说,上代码:

首先说下整个项目的构成,看下图:

大家也看到了,整体代码不多(本来就不是很难的,我比较笨,哈)

package com.example.tabviewtest;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
 * @author ,安
 */
public class TabScrollView extends HorizontalScrollView{

	public static final int MODE_LINE = 0;
	public static final int MODE_NONE = 1;
	private int mMode  = MODE_LINE;
	private View divider;
	private String tabViewTag = "TAB_TAg";
	private String[] titles;
	private DisplayMetrics metrics;
	private int lineWidth;
	private Context context;
	private OnTabClickListener tabClickListener;
	private LinearLayout layout;
	private boolean isScrollable = true;
	private boolean isFirst = true;
	private String tagValue;

	public TabScrollView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		init(context);
	}
	public TabScrollView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		init(context);
	}
	public TabScrollView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
		init(context);
	}

	private void init(Context context){
		this.context = context;
		metrics = getResources().getDisplayMetrics();
		lineWidth = metrics.widthPixels/4;
		layout = new LinearLayout(context);
		layout.setOrientation(LinearLayout.HORIZONTAL);
		layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
		setHorizontalScrollBarEnabled(false);
	}

	private void initTab(){
		switch (mMode) {
		case MODE_LINE:
			addLineTab();
			break;
        case MODE_NONE:
			addNoneTab();
			break;
		default:
			break;
		}
	}

	private void addLineTab(){
		setBackgroundColor(Color.WHITE);
		layout.removeAllViews();
		removeAllViews();
		for (int i = 0; i < titles.length; i++) {
			final View tabView = LayoutInflater.from(context).inflate(R.layout.tabview, null);
			((TextView)tabView.findViewById(R.id.txt_title)).setText(titles[i]);
			((TextView)tabView.findViewById(R.id.txt_title)).setTag(i);
			tabView.setTag("TAB_TAg");
			((ImageView)(tabView.findViewById(R.id.img_tab))).getLayoutParams().width = lineWidth/2;
			tabView.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					Log.i(tabViewTag, ((TextView)tabView.findViewById(R.id.txt_title)).getText().toString());
					scrollToCenter(tabView);
					tabClickListener.onTabClick(TabScrollView.this,tabView);
				}
			});
			layout.addView(tabView,new LayoutParams(lineWidth,LayoutParams.WRAP_CONTENT,Gravity.CENTER));
			addDivider(layout);
		}
		layout.removeViewAt(2*titles.length-1);
		addView(layout);
		hideLine();
	}

	@SuppressLint("NewApi")
	private void addNoneTab(){
		setBackgroundColor(Color.LTGRAY);
		layout.removeAllViews();
		removeAllViews();
		for (int i = 0; i < titles.length; i++) {
			final View tabView = LayoutInflater.from(context).inflate(R.layout.tabview, null);
			((TextView)tabView.findViewById(R.id.txt_title)).setText(titles[i]);
			((TextView)tabView.findViewById(R.id.txt_title)).setTag(i);
			tabView.setTag("TAB_TAg");
			((ImageView)(tabView.findViewById(R.id.img_tab))).getLayoutParams().width = lineWidth/2;
			tabView.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					// TODO Auto-generated method stub
					Log.i(tabViewTag, ((TextView)tabView.findViewById(R.id.txt_title)).getText().toString());
					tabClickListener.onTabClick(TabScrollView.this,tabView);
				}
			});
			layout.addView(tabView,new LayoutParams(lineWidth,LayoutParams.WRAP_CONTENT,Gravity.CENTER));
			addDivider(layout);
		}
		layout.removeViewAt(2*titles.length-1);
		addView(layout);
		hideColor();
		hideLine();
	}

	public void showLine(View v){
		v.findViewById(R.id.img_tab).setVisibility(View.VISIBLE);
		setTagValue((v.findViewById(R.id.txt_title)).getTag().toString());
	}

	public void showColor(View v){
		v.setBackgroundColor(Color.RED);
		setTagValue((v.findViewById(R.id.txt_title)).getTag().toString());
	}

	public void hideLine(){
		for (int i = 0; i < layout.getChildCount(); i++) {
			if (((layout.getChildAt(i)).getTag()) != null) {
				if (isFirst && i == 0 && mMode == MODE_LINE) {
					if (((layout.getChildAt(i)).getTag()).toString().equals(tabViewTag)) {
						(layout.getChildAt(i)).findViewById(R.id.img_tab).setVisibility(View.VISIBLE);
					}
				}else {
					if (((layout.getChildAt(i)).getTag()).toString().equals(tabViewTag)) {
						(layout.getChildAt(i)).findViewById(R.id.img_tab).setVisibility(View.INVISIBLE);
					}
				}
			}
		}
	}

	public void hideColor(){
		for (int i = 0; i < layout.getChildCount(); i++) {
			if (((layout.getChildAt(i)).getTag()) != null) {
				if (isFirst && i == 0 && mMode == MODE_NONE) {
					if (((layout.getChildAt(i)).getTag()).toString().equals(tabViewTag)) {
						(layout.getChildAt(i)).setBackgroundColor(Color.RED);
					}
				}else {
					if (((layout.getChildAt(i)).getTag()).toString().equals(tabViewTag)) {
						(layout.getChildAt(i)).setBackgroundColor(Color.LTGRAY);
					}
				}
			}
		}
	}

	private void addDivider(View v){
		divider = LayoutInflater.from(context).inflate(R.layout.line, null);
		((LinearLayout) v).addView(divider,new LayoutParams(2,
				LayoutParams.MATCH_PARENT,
				Gravity.CENTER));
	}

	private void scrollToCenter(View v){
		if (v.getLeft() >= (lineWidth/2 + lineWidth)) {
			smoothScrollTo(v.getLeft() - lineWidth/2 - lineWidth, 0);
		}else {
			smoothScrollTo(-v.getLeft(), 0);
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		// TODO Auto-generated method stub
		if (isScrollable) {
			return super.onTouchEvent(ev);
		}
		return isScrollable;
	}

	public int getmMode() {
		return mMode;
	}

	public void setmMode(int mMode) {
		this.mMode = mMode;
	}

	public String[] getTitles() {
		return titles;
	}

	public void setTitles(String[] titles) {
		this.titles = titles;
		initTab();
	}
	public OnTabClickListener getTabClickListener() {
		return tabClickListener;
	}
	public void setTabClickListener(OnTabClickListener tabClickListener) {
		this.tabClickListener = tabClickListener;
	}
	public boolean isScrollable() {
		return isScrollable;
	}
	public void setScrollable(boolean isScrollable) {
		this.isScrollable = isScrollable;
	}
	public boolean isFirst() {
		return isFirst;
	}
	public void setFirst(boolean isFirst) {
		this.isFirst = isFirst;
	}
	public String getTagValue() {
		return tagValue;
	}
	public void setTagValue(String tagValue) {
		this.tagValue = tagValue;
	}

}

主要初始化两种模式,这里写的比较死(有空拓展一下),一种是大家看到的有下标的tabview,一种是下面背景色改变的tabview,思路很简单,大家应该都容易看懂,然后这里定义了一个OnTabClickListener,监听tabview的点击事件:

public interface OnTabClickListener {

	void onTabClick(TabScrollView parent,View v);

}

当然还包括两个xml,一个是每个tabview的底层xml,一个是分隔栏的xml:

line.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:gravity="center"
    >

    <ImageView
        android:id="@+id/divider"
        android:layout_width="2dp"
        android:layout_height="wrap_content"
        android:src="@drawable/news_line"
        android:scaleType="center"
        android:layout_marginBottom="2dp"/>

</LinearLayout>

tabview.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    android:padding="5dp"
    >

    <TextView
        android:id="@+id/txt_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="13sp"/>

    <ImageView
        android:id="@+id/img_tab"
        android:layout_width="wrap_content"
        android:layout_height="2dp"
        android:background="#d2232a"
        android:layout_marginTop="2dp"
        android:layout_gravity="center_horizontal|bottom"
        />
</LinearLayout>

接下来就是在自己页面当中引用了,xml如下:

activity_main.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"
    tools:context=".MainActivity"
    android:orientation="vertical" >
<!--    <TextView
    android:id="@+id/id_tv_header_center_tv0"
    android:layout_width="50dp"
    android:layout_height="wrap_content"
    android:text="江湖ersudhfoajfjakfdjsaf看sf艾丝凡的是能否看是否"
    android:ellipsize="marquee"
    android:focusable="true"
	android:marqueeRepeatLimit="marquee_forever"
	android:focusableInTouchMode="true"
	android:scrollHorizontally="true"
    android:singleLine="true"/> -->

    <com.example.tabviewtest.TabScrollView
        android:id="@+id/tabSv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </com.example.tabviewtest.TabScrollView>

    <com.example.tabviewtest.TabScrollView
        android:id="@+id/tabSv2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </com.example.tabviewtest.TabScrollView>
    <WebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

activity代码如下:

package com.example.tabviewtest;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.webkit.WebView;
/**
 * @author ,安
 */
public class MainActivity extends Activity implements OnTabClickListener{

	private static final String TAG = MainActivity.class.getSimpleName();
	private TabScrollView tabSv,tabSv2;
//	private String[] strs = { "550 1.8DWT\n启悦版", "550 1.8DWT\n启智版",
//			"550S 1.8DWT\n智选版(MT)", "550S 1.8DWT\n智选版(6TST)", "550S 1.8DWT\n启逸版",
//			"550S 1.8DWT\n启臻版", "550D 1.8T\n品逸版", "550D 1.8T\n品臻版",
//			"550G 1.8T\n品仕版" };
//	private String[] items = { "基本参数","功力性能","前沿设计","影音娱乐"};
	private String[] strs;
	private String[] items;

	private WebView webView;
	private String urlPrefix = "file:///android_asset/parameter_550_";
	private String urlSuffix = ".html";
	private String initPage = "00";

	private void init(){
		strs = getResources().getStringArray(R.array.car_type);
		items = getResources().getStringArray(R.array.car_param);
	}
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		init();
		tabSv = (TabScrollView)findViewById(R.id.tabSv);
		tabSv.setScrollable(true);              //设置可滚动
		tabSv.setmMode(TabScrollView.MODE_LINE);//设置下面有标签的模式
		tabSv.setTitles(strs);                  //设置tabview的文字显示
		tabSv.setTabClickListener(this);
		tabSv2 = (TabScrollView)findViewById(R.id.tabSv2);
		tabSv2.setScrollable(false);
		tabSv2.setmMode(TabScrollView.MODE_NONE);//设置下面没有标签的模式
		tabSv2.setTitles(items);
		tabSv2.setTabClickListener(this);
		webView = (WebView)findViewById(R.id.webView);
		Log.i(TAG, getAssets().toString());
		loadHtml(initPage);
	}
<pre name="code" class="java">        String partOne = "0";
	String partTwo = "0";

@Overridepublic void onTabClick(TabScrollView parent, View v) {// TODO Auto-generated method stubif (parent == tabSv) {tabSv.setFirst(false);tabSv.hideLine();tabSv.showLine(v);partOne = tabSv.getTagValue();}else if (parent
== tabSv2) {tabSv2.setFirst(false);tabSv2.hideColor();tabSv2.showColor(v);partTwo = tabSv2.getTagValue();}loadHtml(partOne+partTwo);}private void loadHtml(String url){if (url == null || "".equals(url)) {url = initPage;}url = urlPrefix + url + urlSuffix;webView.loadUrl(url);}}


好了,上面就是整个实现,很多地方现在看来都不满意,路过的朋友多指教。

时间: 2024-11-07 18:56:37

HorizontalView实现的tabView的相关文章

Unity NGUI实现Tabview

unity版本:4.5.1 NGUI版本:3.5 参考链接:http://blog.csdn.net/g__dragon/article/details/17242969,作者:CSDN G_Dragon Tabview可以参考NGUI中的示例,场景Examples\Scenes\Example 13 - Tabs 1.用NGUI创建一个2D UI,在该UI Root下新建一个Panel,然后在该Panel下新建两个toggle,在NGUI下创建tab键如下所示: 打开Widget Wizard

tabview分组。仿qq列表

代码如下 #import "ViewController.h" #import "JRProvince.h" @interface ViewController ()<UITableViewDataSource,UITableViewDelegate> /** 省份数据数组*/ @property(nonatomic,strong) NSMutableArray * province; /** 各个地市数据*/ @property(nonatomic,s

解决tabView的滑动和点击

//-------------------首先要遵守UIPanGestureRecognizer代理 @interface HomeController ()<UITableViewDataSource,UIGestureRecognizerDelegate> //----------------定义 UIPanGestureRecognizer属性 @property (nonatomic,strong) UIPanGestureRecognizer *panGestureRecognize

含有scrollView或者tabview页面,坐标下移问题

添加在页面的第一个scrollView或者tabview,它会在自己的顶部预留空白,假如使用navigation自带的bar,那么会预留状态栏和navigationBar的高度,也就是64像素,如果隐藏了navigationBar就只会预留status的高度,也就是20像素 所以,其他添加到scrollView或tabview的元素的起点将会是(0,64)或者(0,20). 假如想去掉此自动留白功能,将以下代码添加到ViewController中 if([[[UIDevice currentDe

iOS 热点、通话时候TabView的Frame调整

- (void)application:(UIApplication *)application didChangeStatusBarFrame:(CGRect)oldStatusBarFrame{ float height = application.statusBarFrame.size.height; CGRect frame = self.mainCtrl.tabView.frame; if (height > 20.0) { frame.origin.y = kDeviceHeight

iOS tabview 适配问题

ios7的UITableView实现ios6的圆角效果 iOS7 UITableView做成类似iOS6风格 在iOS7的时候我们会发现cell的默认线条会向右偏移,使左边空出了一些位置,这时候我们可以调用如下的方法来解决.这样我们的cell就会和iOS6前的一样铺满整个宽度了. if ([tableView respondsToSelector:@selector(setSeparatorInset:)]) { [tableView setSeparatorInset:UIEdgeInsets

QML TabView动态添加tab和赋初值

通过调用TabView的addTab  动态添加新的选项卡:Tab addTab(string title, Component component),其中title为选项卡标题,component为选项卡内的组件(var component = Qt.createComponent("souces.qml"). 动态添加完成后,返回一个Tab,通过引用Tab的item可以访问component内的方法和属性 动态添加Tab和给Tab内的component赋初值源码: var comp

【iOS开发-59】LOL案例:单组tabView、alertView样式、实现监听,以及用reloadData数据刷新

案例效果: (1)先在storyboard中拖拽出一个tableView.然后下面用代码. --tableView继承自scrollView.所以自然有滚动的特性 --最基本的还是数据转模型,以及对cell的赋值 --而cell的赋值那一块,为了优化性能,我们先从tableView的缓存中查找有无被缓存的cell,假设有,直接取出,假设没有再创建.这样提高性能. --这个缓存池是tableView自带的,当滚动的时候,cell不在视线范围内时,这个cell就被放到缓存池里了. #import "

关于tabview的一些小问题

tableview中的cell和底下的线 1 // 刷新指定行数据 2 NSIndexPath *indexPath=[NSIndexPath indexPathForRow:0 inSection:0]; 3 [tab reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath,nil] withRowAnimation:UITableViewRowAnimationNone]; 1 self.tableView.separatorSt