近日由于项目需要自己写了一个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);}}
好了,上面就是整个实现,很多地方现在看来都不满意,路过的朋友多指教。