在写自定控件时,填充自定义控件的属性有两种,一种是直接在布局文件里面添加
xmlns:app="http://schemas.android.com/apk/res-auto"
然后以app:-- 开头的形式直接填充属性,然而这是一种比较呆板的填充方式,我们如何在layout外面动态填充属性呢?其实很简单,直接上代码,下面列举一个在listview里面item相为我们自定义控件。
这是我的自定义控件InfoView
package com.sj.yinjiaoyun.mytest.view; import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.RelativeLayout; import android.widget.TextView; import com.sj.yinjiaoyun.mytest.R; /** * Created by Administrator on 2016/8/18. * 个人资料自定义控件 */ public class InfoView extends RelativeLayout{ Context context; TextView etName;//用户名字 TextView etText;//内容 String TAG="result"; public InfoView(Context context) { super(context); Log.i(TAG, "InfoView: 1"); init(context); } public InfoView(Context context, AttributeSet attrs) { super(context, attrs); Log.i(TAG, "InfoView: 2"); init(context); getValues(attrs); } public InfoView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); Log.i(TAG, "InfoView: 3"); init(context); getValues(attrs); } //初始化控件 private void init(Context context){ Log.i(TAG, "init: "); this.context=context; View view= LayoutInflater.from(context).inflate(R.layout.view_info,this); etName= (TextView) view.findViewById(R.id.view_name); etText= (TextView) view.findViewById(R.id.view_text); } public void getValues(AttributeSet attrs){ Log.i(TAG, "getValues: "); TypedArray array=context.obtainStyledAttributes(attrs, R.styleable.attrs_info); String name=array.getString(R.styleable.attrs_info_attr_name); etName.setText(name); String text=array.getString(R.styleable.attrs_info_attr_text); etText.setText(text); array.recycle(); } /** * 外部设置属性的方法 * @param cName * @param cText */ public void setValues(String cName,String cText){ Log.i(TAG, "setValues: "); etName.setText(cName); etText.setText(cText); } }
自定义控件里面的布局ViewInfo
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp"> <TextView android:id="@+id/view_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dp" /> <TextView android:id="@+id/view_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:alpha="0.7" android:padding="5dp" /> <ImageView android:layout_width="match_parent" android:layout_height="1dp" android:layout_below="@id/view_name" android:background="@color/colorAccent" /> </RelativeLayout>
values里面的设置userInfo
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="attrs_info"> <attr name="attr_name" format="string"/> <attr name="attr_text" format="string"/> </declare-styleable> </resources>
我的程序入口对应的MainActivity类
package com.sj.yinjiaoyun.mytest; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.ListView; import com.sj.yinjiaoyun.mytest.adapter.MyAdapter; import com.sj.yinjiaoyun.mytest.domain.Info; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { List<Info> list; ListView listView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView= (ListView) findViewById(R.id.list_item); list=new ArrayList<>(); for(int i=0;i<20;i++){ list.add(new Info("名字"+i,"内容"+i)); } MyAdapter adapter=new MyAdapter(this,list); listView.setAdapter(adapter); } }
MainActivty加载的布局文件的activity_main
<?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:gravity="center" android:orientation="vertical"> <ListView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/list_item"/> </LinearLayout>
我的adapter类MyAdapter
import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import com.sj.yinjiaoyun.mytest.R; import com.sj.yinjiaoyun.mytest.domain.Info; import com.sj.yinjiaoyun.mytest.view.InfoView; import java.util.List; public class MyAdapter extends BaseAdapter{ Context context; List<Info> list; LayoutInflater inflater; public MyAdapter(Context context, List<Info> list) { this.context = context; this.list = list; inflater=LayoutInflater.from(context); } @Override public int getCount() { return list==null?0:list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { Info info=list.get(position); InfoView infoView = null; if(convertView==null){ convertView=inflater.inflate(R.layout.item_list,null); infoView= (InfoView) convertView.findViewById(R.id.view_info); convertView.setTag(infoView); } infoView= (InfoView) convertView.getTag(); //此处为关键设置值的方法 infoView.setValues(info.getName(),info.getText()); return convertView; } }
下面是我的adapter加载的item_list布局文件
<?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-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <com.sj.yinjiaoyun.mytest.view.InfoView android:id="@+id/view_info" app:attr_name="名字1" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>我的adapter里面传的对象封装类Info
public class Info { String name; String text;//传入string类型的值 public Info(String name, String text) { this.name = name; this.text = text; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getText() { return text; } public void setText(String text) { this.text = text; } }运行该代码后的效果图