Android使用后自定义控件如何在该布局文件以外动态的设置自定义控件的属性

在写自定控件时,填充自定义控件的属性有两种,一种是直接在布局文件里面添加
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>


当我的布局文件在使用自定控件时,我们可以看到log打印出来的是infoView2  init  setValues的先后顺序,


我的程序入口对应的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;
    }
}
运行该代码后的效果图





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值