自定义View
[功能]
1. 自定义View 实现 TextView 的功能
2. 典型的 TextView 如下:
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="HelloTextView" />
就会显示指定的String
[代码]
1. 定义Text2View 所用关键字"text" 用于指定显示用的string
* 在 res/value 目录下创建 attrs.xml 文件 如下定义:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="Text2View"> <attr name="text" format="string" /> </declare-styleable> </resources>
2. 定义 public class Text2View extends View
public class Text2View extends View { Paint text2Paint; String text2Text; int ascent; //Constructor - for java public Text2View(Context context) { super(context); initialize(); } //Constructor - for xml public Text2View(Context context, AttributeSet attrs) { super(context, attrs); initialize(); TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.Text2View); int n = ta.getIndexCount(); for(int i =0;i < n;i++){ int attr = ta.getIndex(i); switch(attr){ case R.styleable.Text2View_text: updateText(ta.getString(R.styleable.Text2View_text)); break; //TO ADD CUSTOM ATTRIBUTE default: break; } } ta.recycle(); } private final void updateText(String s){ text2Text = s; requestLayout(); invalidate(); } //load default setting on Text2View private final void initialize() { text2Paint = new Paint(); text2Paint.setAntiAlias(true); text2Paint.setTextSize(16); text2Paint.setColor(0xFF000000); //setPadding(3, 3, 3, 3); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); } private int measureWidth(int measureSpec) { int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { // We were told how big to be result = specSize; } else { // Measure the text result = (int) text2Paint.measureText(text2Text) + getPaddingLeft() + getPaddingRight(); if (specMode == MeasureSpec.AT_MOST) { // Respect AT_MOST value if that was what is called for by measureSpec result = Math.min(result, specSize); } } return result; } /** * Determines the height of this view * @param measureSpec A measureSpec packed into an int * @return The height of the view, honoring constraints from measureSpec */ private int measureHeight(int measureSpec) { int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); ascent = (int) text2Paint.ascent(); if (specMode == MeasureSpec.EXACTLY) { // We were told how big to be result = specSize; } else { // Measure the text (beware: ascent is a negative number) result = (int) (-ascent + text2Paint.descent()) + getPaddingTop() + getPaddingBottom(); if (specMode == MeasureSpec.AT_MOST) { // Respect AT_MOST value if that was what is called for by measureSpec result = Math.min(result, specSize); } } return result; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawText(text2Text, getPaddingLeft(), getPaddingTop() - ascent, text2Paint); } }
3. Text2View 构造函数需要解释一下:
//Constructor - for java public Text2View(Context context) { super(context); initialize(); } //Constructor - for xml public Text2View(Context context, AttributeSet attrs) { super(context, attrs); initialize(); TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.Text2View); int n = ta.getIndexCount(); for(int i =0;i < n;i++){ int attr = ta.getIndex(i); switch(attr){ case R.styleable.Text2View_text: updateText(ta.getString(R.styleable.Text2View_text)); break; //TO ADD CUSTOM ATTRIBUTE default: break; } } ta.recycle(); }
4. 在 xml 文件中如何使用Text2View
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res/com.android.View" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="HelloTextView" /> <com.android.View.Text2View android:layout_width="fill_parent" android:layout_height="wrap_content" app:text="HelloText2View" /> </LinearLayout>
5. 效果图 和默认的TextView 比较一下
定制化View啊 再作为模板
最近急需这类知识。
那你知道系统的TextView 实现的原理么? 这就是我写这个的本意!
有时候我们需要把程序的raw文件放在sd卡中,其实有时候这样做可以释放资源,有时候可能是使坏呼呼
void copyAssets() { String[] files; try { files = this.getResources().getAssets().list(""); } catch (IOException e1) { return; } if(!mWorkingPath.exists()) { if(!mWorkingPath.mkdirs()) { new AlertDialog.Builder(this) .setTitle(R.string.ERROR) .setMessage(R.string.FAILED_DIR_CREATE) .setPositiveButton(android.R.string.ok, new OnClickListener(){ @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }) .create() .show(); } } for(int i = 0; i < files.length; i++) { try { String fileName = files[i]; if(fileName.compareTo("images") == 0 || fileName.compareTo("sounds") == 0 || fileName.compareTo("webkit") == 0) { continue; } File outFile = new File(mWorkingPath, fileName); if(outFile.exists()) continue; InputStream in = getAssets().open(fileName); OutputStream out = new FileOutputStream(outFile); // Transfer bytes from in to out byte[] buf = new byte[1024]; int len; while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); } in.close(); out.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
当更改每个item点击后出现不同的颜色的方法;
<style name="Widget.AbsListView"> <item name="android:listSelector">@drawable/my_selector</item> </style>
my_selector在drawable
<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2008 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_window_focused="false" android:drawable="@color/transparent" /> <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. --> <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/list_selector_background_disabled" /> <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/list_selector_background_disabled" /> <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition" /> <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition" /> <item android:state_focused="true" android:drawable="@drawable/list_selector_background_focus" /> </selector>
我想在代码中实现
public View getView(final int position, View convertView, ViewGroup parent) { int colorPos = position % colors.length; ... convertView.setBackgroundColor(colors[colorPos]); return convertView; }
可是没有成功 是不是没有刷新呢 画面呢
根据上面都没有成功,我看了好多有的成功有的没有成功不知道怎么弄的 就连第一种也没成功
color.xml
<resources>
<drawable name="list_normal">#96FFFFFF</drawable>
<drawable name="list_active">#66000000</drawable>
<drawable name="list_pressed">#CA000000</drawable>
</resources>
listview_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:state_focused="true"
android:drawable="@drawable/list_normal" />
<item android:state_pressed="true"
android:drawable="@drawable/list_pressed" />
<item android:state_focused="true"
android:drawable="@drawable/list_active" />
</selector>
还有的呢使用
然后
On ListView, set android:listSelector="@android:color/transparent".
************************************************************************
本来这个问题就留在这里的,不过那天一个网友一直向实现而不能实现,我就和他一起讨论很久试了很多方法,最后发现无论怎么样都是系统的颜色,后来我发现我们用的是listAvtivity,根本没有使用xml中的listActivty,所以我就把那些样式用在了主题当中结果可行 如下面的附件。
如果想按照以前上面的那些方法,那必须不能用listActivity本身的activity,或者直接用activity从里面找到lisView
总之你想用上面的方法 就是***上面的方法,我想你必须用你自己的listVIew而不是系统的。这只是我的猜想没有去实现嘿嘿。
最后又通过修改getView 证明也是可一的。
public class StyledListItems extends ListActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.list); setListAdapter(new StyledListItemAdapter(this)); } private class StyledListItemAdapter extends BaseAdapter { public StyledListItemAdapter(Context context) { mContext = context; } public int getCount() { return mTitles.length; } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { sv = new StyledItemView(mContext, mTitles[position]); } else { sv = (StyledItemView) convertView; } sv.setContent(mTitles[position]); return sv; } private Context mContext; private String[] mTitles = { "lorem dipsum", "lorem dipsum", "lorem dipsum", "lorem dipsum", "lorem dipsum", "lorem dipsum", "lorem dipsum", "lorem dipsum" }; } private class StyledItemView extends LinearLayout { private LayoutInflater mInflater; public StyledItemView(Context context, String title) { super(context); this.setOrientation(VERTICAL); mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); LinearLayout layout = (LinearLayout)mInflater.inflate(R.layout.list_item, null); mTitle = (TextView)layout.findViewById(R.id.txt_item); addView(layout); } public void setContent(String title) { mTitle.setText(title); } private TextView mTitle; } StyledItemView sv; }
list——tem
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/div_list_item" android:background="@drawable/list_item_style" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/txt_item" android:layout_width="fill_parent" android:textSize="14sp" android:layout_height="20dip" /> </LinearLayout>
android:background="@drawable/list_item_style"
就是要变化的背景
The items in ListView is TextView, as below:
<?xml version="1.0" encoding="utf-8"?>
<TextView android:id="@+id/phone_numbers_row_text_tv"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/list_view_selector"
android:gravity="center"
/>
The "list_view_selector" is as below:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_selected="true"
android:drawable="@drawable/number_select_bg"/>
<item
android:state_pressed="true"
android:drawable="@drawable/number_select_bg"/>
<item
android:state_focused="true"
android:drawable="@drawable/number_select_bg"/>
<item
android:drawable="@drawable/number_bg"/>
</selector>