Android 快速开发系列 打造万能的ListView GridView 适配器

Cadence IC618版图DRC验证License报错排查:从虚拟机网络配置到HOSTID的实战解析 本文详细解析了Cadence IC618版图设计中DRC验证License报错的排查方法,重点从虚拟机网络配置到HOSTID获取的实战经验。通过对比ifconfig与ip add命令的差异,提供了正确的HOSTID获取方式及License文件修改技巧,帮助工程师快速解决IC618环境下的DRC验证问题。 阅读详情

1、概述

相信做Android开发的写得最多的就是ListView,GridView的适配器吧,记得以前开发一同事开发项目,一个项目下来基本就一直在写ListView的Adapter都快吐了~~~对于Adapter一般都继承BaseAdapter复写几个方法,getView里面使用ViewHolder模式,其实大部分的代码基本都是类似的。

本篇博客为快速开发系列的第一篇,将一步一步带您封装出一个通用的Adapter。

2、常见的例子

首先看一个最常见的案例,大家一目十行的扫一眼

1、布局文件

主布局文件:

 

?
1
2
3
4
5
<relativelayout android:layout_height= "match_parent" android:layout_width= "match_parent" xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools= "http://schemas.android.com/tools" >
 
     <listview android:id= "@+id/id_lv_main" android:layout_height= "fill_parent" android:layout_width= "fill_parent" >
 
</listview></relativelayout>

Item的布局文件:

 

 

?
1
2
3
4
<!--?xml version= 1.0 encoding=utf- 8 ?-->
<textview android:background= "#aa111111" android:gravity= "center_vertical" android:id= "@+id/id_tv_title" android:layout_height= "50dp" android:layout_width= "match_parent" android:paddingleft= "15dp" android:text= "hello" android:textcolor= "#ffffff" android:textsize= "20sp" android:textstyle= "bold" xmlns:android= "http://schemas.android.com/apk/res/android" >
 
</textview>

2、Adapter

 

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package com.example.zhy_baseadapterhelper;
 
import java.util.List;
 
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
 
public class MyAdapter extends BaseAdapter
{
     private LayoutInflater mInflater;
     private Context mContext;
     private List<string> mDatas;
 
     public MyAdapter(Context context, List<string> mDatas)
     {
         mInflater = LayoutInflater.from(context);
         this .mContext = context;
         this .mDatas = mDatas;
     }
 
     @Override
     public int getCount()
     {
         return mDatas.size();
     }
 
     @Override
     public Object getItem( int position)
     {
         return mDatas.get(position);
     }
 
     @Override
     public long getItemId( int position)
     {
         return position;
     }
 
     @Override
     public View getView( int position, View convertView, ViewGroup parent)
     {
         ViewHolder viewHolder = null ;
         if (convertView == null )
         {
             convertView = mInflater.inflate(R.layout.item_single_str, parent,
                     false );
             viewHolder = new ViewHolder();
             viewHolder.mTextView = (TextView) convertView
                     .findViewById(R.id.id_tv_title);
             convertView.setTag(viewHolder);
         } else
         {
             viewHolder = (ViewHolder) convertView.getTag();
         }
         viewHolder.mTextView.setText(mDatas.get(position));
         return convertView;
     }
 
     private final class ViewHolder
     {
         TextView mTextView;
     }
 
}
</string></string>

3、Activity

 

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.example.zhy_baseadapterhelper;
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
 
public class MainActivity extends Activity
{
 
     private ListView mListView;
     private List<string> mDatas = new ArrayList<string>(Arrays.asList(Hello,
             World, Welcome));
     private MyAdapter mAdapter;
 
     @Override
     protected void onCreate(Bundle savedInstanceState)
     {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         mListView = (ListView) findViewById(R.id.id_lv_main);
         mListView.setAdapter(mAdapter = new MyAdapter( this , mDatas));
 
     }
 
}
</string></string>

上面这个例子大家应该都写了无数遍了,MyAdapter集成BaseAdapter,然后getView里面使用ViewHolder模式;一般情况下,我们的写法是这样的:对于不同布局的ListView,我们会有一个对应的Adapter,在Adapter中又会有一个ViewHolder类来提高效率。

 

这样出现ListView就会出现与之对于的Adapter类、ViewHolder类;那么有没有办法减少我们的编码呢?

下面首先拿ViewHolder开刀~

3、通用的ViewHolder

首先分析下ViewHolder的作用,通过convertView.setTag与convertView进行绑定,然后当convertView复用时,直接从与之对于的ViewHolder(getTag)中拿到convertView布局中的控件,省去了findViewById的时间~

也就是说,实际上们每个convertView会绑定一个ViewHolder对象,这个viewHolder主要用于帮convertView存储布局中的控件。

那么我们只要写出一个通用的ViewHolder,然后对于任意的convertView,提供一个对象让其setTag即可;

既然是通用,那么我们这个ViewHolder就不可能含有各种控件的成员变量了,因为每个Item的布局是不同的,最好的方式是什么呢?

提供一个容器,专门存每个Item布局中的所有控件,而且还要能够查找出来;既然需要查找,那么ListView肯定是不行了,需要一个键值对进行保存,键为控件的Id,值为控件的引用,相信大家立刻就能想到Map;但是我们不用Map,因为有更好的替代类,就是我们android提供的SparseArray这个类,和Map类似,但是比Map效率,不过键只能为Integer.

下面看我们的ViewHolder类:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package com.example.zhy_baseadapterhelper;
 
import android.content.Context;
import android.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
 
public class ViewHolder
{
     private final SparseArray<view> mViews;
     private View mConvertView;
 
     private ViewHolder(Context context, ViewGroup parent, int layoutId,
             int position)
     {
         this .mViews = new SparseArray<view>();
         mConvertView = LayoutInflater.from(context).inflate(layoutId, parent,
                 false );
         //setTag
         mConvertView.setTag( this );
         
         
     }
 
     /**
      * 拿到一个ViewHolder对象
      * @param context
      * @param convertView
      * @param parent
      * @param layoutId
      * @param position
      * @return
      */
     public static ViewHolder get(Context context, View convertView,
             ViewGroup parent, int layoutId, int position)
     {
     
         if (convertView == null )
         {
             return new ViewHolder(context, parent, layoutId, position);
         }
         return (ViewHolder) convertView.getTag();
     }
 
 
     /**
      * 通过控件的Id获取对于的控件,如果没有则加入views
      * @param viewId
      * @return
      */
     public <t extends = "" view= "" > T getView( int viewId)
     {
         
         View view = mViews.get(viewId);
         if (view == null )
         {
             view = mConvertView.findViewById(viewId);
             mViews.put(viewId, view);
         }
         return (T) view;
     }
 
     public View getConvertView()
     {
         return mConvertView;
     }
 
     
 
}
</t></view></view>


 

与传统的ViewHolder不同,我们使用了一个SparseArray用于存储与之对于的convertView的所有的控件,当需要拿这些控件时,通过getView(id)进行获取;

下面看使用该ViewHolder的MyAdapter;

 

?
1
2
3
4
5
6
7
8
9
10
11
12
@Override
     public View getView( int position, View convertView, ViewGroup parent)
     {
         //实例化一个viewHolder
         ViewHolder viewHolder = ViewHolder.get(mContext, convertView, parent,
                 R.layout.item_single_str, position);
         //通过getView获取控件
         TextView tv = viewHolder.getView(R.id.id_tv_title);
         //使用
         tv.setText(mDatas.get(position));
         return viewHolder.getConvertView();
     }

只看getView,其他方法都一样;首先调用ViewHolder的get方法,如果convertView为null,new一个ViewHolder实例,通过使用mInflater.inflate加载布局,然后new一个SparseArray用于存储View,最后setTag(this);

 

如果存在那么直接getTag

最后通过getView(id)获取控件,如果存在则直接返回,否则调用findViewById,返回存储,返回。

好了,一个通用的ViewHolder写好了,以后一个项目几十个Adapter一个ViewHolder直接hold住全场~~大家可以省点时间斗个小地主了~~

4、打造通用的Adapter

有了通用的ViewHolder大家肯定不能满足,怎么也得省出dota的时间,人在塔在~~

下面看如何打造一个通过的Adapter,我们叫做CommonAdapter

继续分析,Adapter一般需要保持一个List对象,存储一个Bean的集合,不同的ListView,Bean肯定是不同的,这个CommonAdapter肯定需要支持泛型,内部维持一个List,就解决我们的问题了;

于是我们初步打造我们的CommonAdapter

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package com.example.zhy_baseadapterhelper;
 
import java.util.List;
 
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
 
public abstract class CommonAdapter<t> extends BaseAdapter
{
     protected LayoutInflater mInflater;
     protected Context mContext;
     protected List<t> mDatas;
 
     public CommonAdapter(Context context, List<t> mDatas)
     {
         mInflater = LayoutInflater.from(context);
         this .mContext = context;
         this .mDatas = mDatas;
     }
 
     @Override
     public int getCount()
     {
         return mDatas.size();
     }
 
     @Override
     public Object getItem( int position)
     {
         return mDatas.get(position);
     }
 
     @Override
     public long getItemId( int position)
     {
         return position;
     }
 
}
</t></t></t>
我们的CommonAdapter依然是一个抽象类,除了getView以外我们把其他的代码都实现了,这样的话,在使用我们的Adapter只要实现一个getView,然后getView里面再使用我们打造的通过的ViewHolder是不是感觉还不错~

 

现在我们的MyAdapter是这样的:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.example.zhy_baseadapterhelper;
 
import java.util.List;
 
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
 
public class MyAdapter<t> extends CommonAdapter<t>
{
     public MyAdapter(Context context, List<t> mDatas)
     {
         super (context, mDatas);
     }
 
     @Override
     public View getView( int position, View convertView, ViewGroup parent)
     {
         ViewHolder viewHolder = ViewHolder.get(mContext, convertView, parent,
                 R.layout.item_single_str, position);
         TextView mTitle = viewHolder.getView(R.id.id_tv_title);
         mTitle.setText((String) mDatas.get(position));
         return viewHolder.getConvertView();
     }
 
}
</t></t></t>

所有的代码加起来也就10行左右,是不是神清气爽~~稍等,我先去dota一把~

 

但是我们是否就这样满足了呢?显然还可以简化。

5、进一步铸造

注意我们的getView里面的代码,虽然只有4行,但是我觉得所有的Adapter的

第一行(ViewHolder viewHolder = getViewHolder(position, convertView,parent);)和

最后一行:return viewHolder.getConvertView();一定是一样的。

那么我们可以这样做:我们把第一行和最后一行写死,把中间变化的部分抽取出来,这不就是OO的设计原则嘛。现在CommonAdapter是这样的:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package com.example.zhy_baseadapterhelper;
 
import java.util.List;
 
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
 
public abstract class n<t> extends BaseAdapter
{
     protected LayoutInflater mInflater;
     protected Context mContext;
     protected List<t> mDatas;
     protected final int mItemLayoutId;
 
     public CommonAdapter(Context context, List<t> mDatas, int itemLayoutId)
     {
         this .mContext = context;
         this .mInflater = LayoutInflater.from(mContext);
         this .mDatas = mDatas;
         this .mItemLayoutId = itemLayoutId;
     }
 
     @Override
     public int getCount()
     {
         return mDatas.size();
     }
 
     @Override
     public T getItem( int position)
     {
         return mDatas.get(position);
     }
 
     @Override
     public long getItemId( int position)
     {
         return position;
     }
 
     @Override
     public View getView( int position, View convertView, ViewGroup parent)
     {
         final ViewHolder viewHolder = getViewHolder(position, convertView,
                 parent);
         convert(viewHolder, getItem(position));
         return viewHolder.getConvertView();
 
     }
 
     public abstract void convert(ViewHolder helper, T item);
 
     private ViewHolder getViewHolder( int position, View convertView,
             ViewGroup parent)
     {
         return ViewHolder.get(mContext, convertView, parent, mItemLayoutId,
                 position);
     }
 
}
</t></t></t>

对外公布了一个convert方法,并且还把viewHolder和本Item对于的Bean对象给传出去,现在convert方法里面需要干嘛呢?

 

通过ViewHolder把View找到,通过Item设置值;

现在我觉得代码简化到这样,我已经不需要单独写一个Adapter了,直接MainActivity匿名内部类走起~

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Override
     protected void onCreate(Bundle savedInstanceState)
     {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         mListView = (ListView) findViewById(R.id.id_lv_main);
 
         //设置适配器
         mListView.setAdapter(mAdapter = new CommonAdapter<string>(
                 getApplicationContext(), mDatas, R.layout.item_single_str)
         {
             @Override
             public void convert(ViewHolder c, String item)
             {
                 TextView view = viewHolder.getView(R.id.id_tv_title);
                 view.setText(item);
             }
 
         });
 
     }</string>

可以看到效果咋样,不错吧。你觉得还能简化么?我觉得还能改善。

 

6、Adapter最后的封魔

我们现在在convertView里面需要这样:

@Override
public void convert(ViewHolder viewHolder, String item)
{
TextView view = viewHolder.getView(R.id.id_tv_title);
view.setText(item);
}

我们细想一下,其实布局里面的View常用也就那么几种:ImageView,TextView,Button,CheckBox等等;

那么我觉得ViewHolder还可以封装一些常用的方法,比如setText(id,String);setImageResource(viewId, resId);setImageBitmap(viewId, bitmap);

那么现在ViewHolder是:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package com.example.zhy_baseadapterhelper;
 
import android.content.Context;
import android.graphics.Bitmap;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
 
import com.example.zhy_baseadapterhelper.ImageLoader.Type;
 
public class ViewHolder
{
     private final SparseArray<view> mViews;
     private int mPosition;
     private View mConvertView;
 
     private ViewHolder(Context context, ViewGroup parent, int layoutId,
             int position)
     {
         this .mPosition = position;
         this .mViews = new SparseArray<view>();
         mConvertView = LayoutInflater.from(context).inflate(layoutId, parent,
                 false );
         // setTag
         mConvertView.setTag( this );
     }
 
     /**
      * 拿到一个ViewHolder对象
      *
      * @param context
      * @param convertView
      * @param parent
      * @param layoutId
      * @param position
      * @return
      */
     public static ViewHolder get(Context context, View convertView,
             ViewGroup parent, int layoutId, int position)
     {
         if (convertView == null )
         {
             return new ViewHolder(context, parent, layoutId, position);
         }
         return (ViewHolder) convertView.getTag();
     }
 
     public View getConvertView()
     {
         return mConvertView;
     }
 
     /**
      * 通过控件的Id获取对于的控件,如果没有则加入views
      *
      * @param viewId
      * @return
      */
     public <t extends = "" view= "" > T getView( int viewId)
     {
         View view = mViews.get(viewId);
         if (view == null )
         {
             view = mConvertView.findViewById(viewId);
             mViews.put(viewId, view);
         }
         return (T) view;
     }
 
     /**
      * 为TextView设置字符串
      *
      * @param viewId
      * @param text
      * @return
      */
     public ViewHolder setText( int viewId, String text)
     {
         TextView view = getView(viewId);
         view.setText(text);
         return this ;
     }
 
     /**
      * 为ImageView设置图片
      *
      * @param viewId
      * @param drawableId
      * @return
      */
     public ViewHolder setImageResource( int viewId, int drawableId)
     {
         ImageView view = getView(viewId);
         view.setImageResource(drawableId);
 
         return this ;
     }
 
     /**
      * 为ImageView设置图片
      *
      * @param viewId
      * @param drawableId
      * @return
      */
     public ViewHolder setImageBitmap( int viewId, Bitmap bm)
     {
         ImageView view = getView(viewId);
         view.setImageBitmap(bm);
         return this ;
     }
 
     /**
      * 为ImageView设置图片
      *
      * @param viewId
      * @param drawableId
      * @return
      */
     public ViewHolder setImageByUrl( int viewId, String url)
     {
         ImageLoader.getInstance( 3 , Type.LIFO).loadImage(url,
                 (ImageView) getView(viewId));
         return this ;
     }
 
     public int getPosition()
     {
         return mPosition;
     }
 
}
</t></view></view>

现在的MainActivity只需要这么写:

 

 

?
1
2
3
4
5
6
7
8
9
mAdapter = new CommonAdapter<string>(getApplicationContext(),
                 R.layout.item_single_str, mDatas)
         {
             @Override
             protected void convert(ViewHolder viewHolder, String item)
             {
                 viewHolder.setText(R.id.id_tv_title, item);
             }
         };</string>

convertView里面只要一行代码了~~~

 

好了,到此我们的通用的Adapter已经一步一步铸造完毕~咋样,以后写项目省下来的时间是不是可以陪我切磋dota了(ps:11昵称:血魔哥404)~~

注:关于ViewHolder里面的setText,setImageResource这类的方法,大家可以在使用的过程中不断的完善,今天发现这个控件可以这么设置值,好,放进去;时间长了,基本就完善了。还有那个ImageLoader是我另一篇博客里的,大家可以使用UIL,Volley或者自己写个图片加载器;

7、实践

说了这么多,还是得拿出来让我们的实践检验检验,顺便来几张套图,俗话说,没图没正相。

1、我们的实例代码的图是这样的:

/

关于Adapter和ViewHolder的代码是这样的:

 

?
1
2
3
4
5
6
7
8
9
10
11
// 设置适配器
         mListView.setAdapter(mAdapter = new CommonAdapter<string>(
                 getApplicationContext(), mDatas, R.layout.item_single_str)
         {
             @Override
             public void convert(ViewHolder helper, String item)
             {
                 helper.setText(R.id.id_tv_title,item);
             }
 
         });</string>

哎哟,我是不是只要贴一行;

 

2、来个复杂点的布局

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!--?xml version= 1.0 encoding=utf- 8 ?-->
<relativelayout android:background= "#ffffff" android:layout_height= "wrap_content" android:layout_width= "match_parent" android:orientation= "vertical" android:padding= "10dp" xmlns:android= "http://schemas.android.com/apk/res/android" >
 
     <textview android:id= "@+id/tv_title" android:layout_height= "wrap_content" android:layout_width= "match_parent" android:singleline= "true" android:text= "红色钱包" android:textcolor= "#444444" android:textsize= "16sp" >
     </textview>
 
     <textview android:id= "@+id/tv_describe" android:layout_below= "@id/tv_title" android:layout_height= "wrap_content" android:layout_margintop= "10dp" android:layout_width= "match_parent" android:maxlines= "2" android:minlines= "1" android:text= "周三早上丢失了红色钱包,在食堂二楼" android:textcolor= "#898989" android:textsize= "16sp" >
     </textview>
 
     <textview android:id= "@+id/tv_time" android:layout_below= "@id/tv_describe" android:layout_height= "wrap_content" android:layout_margintop= "10dp" android:layout_width= "wrap_content" android:text= "20130240122" android:textcolor= "#898989" android:textsize= "12sp" >
     </textview>
 
     <textview android:background= "#5cbe6c" android:drawableleft= "@drawable/icon_photo" android:drawablepadding= "5dp" android:id= "@+id/tv_phone" android:layout_alignparentright= "true" android:layout_below= "@id/tv_describe" android:layout_height= "wrap_content" android:layout_margintop= "10dp" android:layout_width= "wrap_content" android:paddingbottom= "3dp" android:paddingleft= "5dp" android:paddingright= "5dp" android:paddingtop= "3dp" android:text= "138024249542" android:textcolor= "#ffffff" android:textsize= "12sp" >
     </textview>
 
</relativelayout>

效果图是这样的:

 

/

布局是不是挺复杂的了~~

但是代码是这样的:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 设置适配器
         mListView.setAdapter(mAdapter = new CommonAdapter<bean>(
                 getApplicationContext(), mDatas, R.layout.item_list)
         {
             @Override
             public void convert(ViewHolder helper, Bean item)
             {
                 helper.setText(R.id.tv_title, item.getTitle());
                 helper.setText(R.id.tv_describe, item.getDesc());
                 helper.setText(R.id.tv_phone, item.getPhone());
                 helper.setText(R.id.tv_time, item.getTime());
                 
//              helper.getView(R.id.tv_title).setOnClickListener(l)
             }
 
         });</bean>

从一个字符串的布局到这样的布局,Adapter加ViewHolder的改变就这么多,加起来3行左右代码~~~

 

 

到此,Android 快速开发系列 打造万能的ListView GridView 适配器结束;

 

最后给大家推荐一个gitHub项目:https://github.com/JoanZapata/base-adapter-helper ,这个项目所做的,和我上面写的基本一致。

还有上面的布局文件来自网络,感谢Bmob的提供~

好了,我要去快乐的玩耍了~~

OpenHarmony RK3568 从 32 位切换到 64 位用户空间指南 修改了编译参数(如修复 Q5 后),但 ThinLTO 缓存中保留了旧参数编译的 bitcode。这是一种节省内存的设计(32 位指针占 4 字节 vs 64 位占 8 字节),但在某些场景下需要切换为纯 64 位。切换到 64 位用户空间后,CPU 全程运行在 AArch64 状态,不再需要 AArch32 兼容模式。内核本身已经是 64 位(aarch64),切换用户空间位数不影响内核。(32 位兼容层)在纯 64 位系统中不再需要,可以关闭以减小内核体积。这两个参数对 64 位编译毫无意义,配合。 阅读详情

相关推荐

用Python和NumPy搞定复合材料层合板ABD矩阵计算(附完整代码与避坑指南)

本文详细介绍了如何使用Python和NumPy高效计算复合材料层合板的ABD刚度矩阵,包括单层板刚度计算、偏轴转换和层合板刚度集成。通过完整的代码示例和工程实践技巧,帮助工程师快速构建定制化分析工具,解决航空航天、汽车制造等领域的复合材料力学性能分析问题。特别提供了避坑指南和性能优化策略,确保计算结果的准确性和效率。

weixin_30752699的博客 280

Android性能:经典ListView适配器convertView缓存及复用机制

Android性能:经典ListView适配器convertView缓存及复用机制Android中的ListView常用Adapter中都会涉及到convertView的使用,使用convertView主要是为了缓存试图View,用以增加ListView的item view加载效率。有经验的Android开发者通常知道在Adapter的getView中,先判断convertView是否为空null

Zhang Phil 2万+

AutoCAD2014与ObjectARX开发环境搭建实战指南

本文提供了一份详细的AutoCAD2014与ObjectARX开发环境搭建实战指南。内容涵盖从AutoCAD2014、Visual Studio 2010及ObjectARX 2014 SDK的版本匹配与环境准备,到Wizard安装、编码问题解决、Visual Studio配置,并最终通过一个完整的绘图命令开发示例,手把手引导开发者创建并加载第一个可运行的ObjectARX插件,为后续深入开发奠定坚实基础。

weixin_28475533的博客 289

Android打造ListView和GridView万能适配器

本篇博客是我学习过慕课网的《Android-打造万能适配器》课程后的学习笔记一、传统方式分析  传统写法下,我们几乎每个ListView都会单独写一个Adapter和一个ViewHolder,分析代码可以发现,传统的Adapter里有很多的重复性代码,比如说getCount()、getItem(int position)、getItemId(int position),传统Adapter写法如下:p

playing_the_fool的博客 990

多旋翼飞行器设计与控制·Pixhawk4以及外部设备接线(笔记004)

笔记主要来源:Pixhawk 4 接线快速入门 目录 一、Pixhawk 4 的各个接口 二、接线图概览(重要传感器及外围设备) 三、飞控、GPS的安装和方向 四、电源 五、无线电遥控 六、数传电台(可选) 七、SD Card(可选) 八、电机以及其他外设 一、Pixhawk 4 的各个接口 FMU:Flight Management Unit 飞行管理组件 主 FMU 处理器:STM32F765 32 位 Arm® Cortex®-M7,216MHz,2MB...

猪猪的博客 1万+

工业视觉开发者的福音:用C#玩转VisionMaster算子(非方案版完整教程)

本文为工业视觉开发者提供了一份完整的C#与VisionMaster算子二次开发教程,详细介绍了环境配置、算子调用原理、性能优化技巧及实战案例。通过模板匹配和二维码识别等实例,展示了如何高效集成VisionMaster算子到现有框架中,提升工业自动化视觉检测系统的灵活性和性能。

weixin_29280657的博客 273

对convertView和ViewHolder的理解

在使用listview和recyclerview的过程中免不了要用到convertview和viewholder,所以理解他们的工作原理还是很有意义的。 首先来看listview的使用,如果要写一个最简单的BaseAdapter的话,那么getView中直接用LayoutInflater根据布局文件生成一个View,然后再获取这个view的子组件设置属性,返回这个view就可以了。但是这

zhang___yong的博客 8469

SRAM Bank数量配置:性能、面积与功耗的权衡指南

SRAM(静态随机存取存储器)是芯片设计中的关键存储单元,其Bank数量配置直接影响访问延迟、吞吐率、功耗和面积。Bank切分通过将存储阵列分区,缩短位线和字线延迟,从而提升性能,但会增加外围电路开销。合理配置Bank数量可优化PPA(性能、功耗、面积),在28nm和16nm工艺下,2个Bank通常是性价比最高的选择。本文基于实测数据,探讨不同场景下的Bank配置策略,帮助工程师避免常见误区,提升设计效率。

weixin_27230891的博客 179

android 添加一维数组,Android:打造“万能”Adapter与ViewHolder

写在前面最近一直忙着各种结课大作业,重新看起Android还有种亲切感。前段时间写项目的时候,学习了一个万能Adapter与ViewHolder的写法。说是“万能”其实就是在各种情况下都能通用。我们知道,在写项目的时候,项目中肯定有很多的ListView或者RecyclerView,这个时候我们就要写大量的Adapter与ViewHolder。尽管重复写的难度并不大,但是这会让项目看起来十分冗余,...

weixin_31783001的博客 495

Windows服务器XMRig挖矿病毒深度清除实战指南

XMRig是一种广泛用于Monero(XMR)加密货币挖矿的开源工具,其在Windows环境中的持久化机制已远超传统木马范畴,融合WMI事件订阅、服务伪装、PowerShell无文件执行与注册表隐写等多重反检测技术。理解其基于行为而非特征的生存逻辑,是实现有效检测与根除的前提。该技术具备强隐蔽性、高自愈性与网络通信合法化特征,常见于RDP弱口令爆破、SMB共享泄露及PowerShell远程执行等非漏洞类入侵场景。本文聚焦Windows原生命令与Sysinternals工具链,提供覆盖进程定位、WMI清理、服

weixin_30535843的博客 735

(功能安全六)硬件FMEDA计算

FMEDA(故障模式、影响与诊断分析)是功能安全验证的核心方法,通过量化分析硬件故障模式及其影响,计算SPFM、LFM、PMHF等关键指标。分析过程包含六大步骤:计算元器件失效率、识别故障模式、评估安全机制诊断覆盖率、分类计算各类失效率、量化指标计算及设计优化。输入需要系统架构图、硬件故障模式清单等资料,输出安全指标达标情况及改进建议,确保设计满足ASIL等级要求。该方法通过系统化的故障分类和量化评估,为硬件安全设计提供科学依据。

Dayongger的博客 1454
上一篇: android颜色对应的xml配置值,颜色表
下一篇: Picasso:一个强大的图片下载和缓存库
codepython
博客等级 码龄20年 125粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值