首页 文章 精选 留言 我的

精选列表

搜索[UI库],共10000篇文章
优秀的个人博客,低调大师

UI组件-ViewAnimator及其子类

前言 凡事不必太在意,一切随缘随心,缘深多聚聚,缘浅随它去。 ViewSwitcher的功能与用法 ViewSwitcher代表了视图切换组件,它本身继承了FrameLayout,因此可以将多个View层叠在一起,每次只显示一个组件。当程序控制从一个View切换到另一个View时,ViewSwitcher支持指定的动画。下面来看看仿Android系统Launcher界面示例。假设一共有100个应用程序,每个页面显示20个,每行4个。 代码示例 activity_main.xml <RelativeLayout 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" > <!-- 定义个一个ViewSwitcher组件 --> <ViewSwitcher android:id="@+id/viewSwitcher" android:layout_width="match_parent" android:layout_height="match_parent" /> <!-- 定义滚动到上一屏的按钮 --> <Button android:id="@+id/button_prev" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:onClick="prev" android:text="<" /> <!-- 定义滚动到下一屏的按钮 --> <Button android:id="@+id/button_next" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:onClick="next" android:text=">" /> </RelativeLayout> labelicon.xml <?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:orientation="vertical" android:gravity="center"> <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" /> </LinearLayout> slidelistview.xml <?xml version="1.0" encoding="utf-8"?> <GridView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:numColumns="4" android:gravity="center" /> slide_in_left.xml <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 设置从右边拖进来的动画,android:duration指定动画持续时间 --> <translate android:fromXDelta="0" android:toXDelta="100%p" android:duration="@android:integer/config_mediumAnimTime" /> </set> slide_out_right.xml <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 设置从左边拖出去的动画,android:duration指定动画持续时间 --> <translate android:fromXDelta="-100%p" android:toXDelta="0" android:duration="@android:integer/config_mediumAnimTime" /> </set> slide_in_right.xml <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 设置从右边拖进来的动画,android:duration指定动画持续时间 --> <translate android:fromXDelta="100%p" android:toXDelta="0" android:duration="@android:integer/config_mediumAnimTime" /> </set> slide_out_left.xml <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 设置从左边拖出去的动画,android:duration指定动画持续时间 --> <translate android:fromXDelta="0" android:toXDelta="-100%p" android:duration="@android:integer/config_mediumAnimTime" /> </set> MainActivity.java public class MainActivity extends Activity { //定义一个常量,用于显示每屏显示的应用程序数 public static final int NUMER_PER_SCREEN = 20; //代表应用程序的内部类 public static class DataItem { //应用程序名称 public String dataName; //应用程序图片 public Drawable drawable; } //保存系统所有应用程序的List集合 private ArrayList<DataItem> items = new ArrayList<DataItem>(); //记录当前正在显示第几屏的程序 private int screenNo = -1; //保存程序所占的总屏数 private int screenCount; ViewSwitcher switcher; //创建LayoutInflater对象 LayoutInflater inflater; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); inflater = LayoutInflater.from(MainActivity.this); //创建一个包含100个元素的list集合,用于模拟包含100个应用程序 for (int i = 0; i < 100; i++) { String label = "" + i; Drawable drawable = getResources().getDrawable(R.drawable.ic_launcher); DataItem item = new DataItem(); item.dataName = label; item.drawable = drawable; items.add(item); } //计算应用程序所占的总屏数 //如果应用程序的数量能整除NUMBER_PER_SCREEN,除法的结果就是总屏数 //如果不能整除,总屏数应该是除法的结果加1 screenCount = items.size() % NUMER_PER_SCREEN == 0 ? items.size() / NUMER_PER_SCREEN : items.size() / NUMER_PER_SCREEN + 1; switcher = (ViewSwitcher) findViewById(R.id.viewSwitcher); switcher.setFactory(new ViewFactory() { //实际上是返回一个GridView组件 @Override public View makeView() { //加载R.Layout。slidelistview组件,实际上就是一个GridView return inflater.inflate(R.layout.slidelistview, null); } }); next(null); } public void next(View v) { if(screenNo < screenCount - 1) { screenNo++; //为ViewSwitcher的组件显示过程设置动画 switcher.setInAnimation(this,R.anim.slide_in_right); //为ViewSwitcher的组件隐藏过程设置动画 switcher.setInAnimation(this,R.anim.slide_out_left); //控制下一屏将要显示的GridView对应的Adapter ((GridView)switcher.getNextView()).setAdapter(adapter); //单击右边按钮,显示下一屏 switcher.showNext(); } } public void prev(View v) { if(screenNo > 0) { screenNo--; //为ViewSwitcher的组件显示过程设置动画 switcher.setInAnimation(this,R.anim.slide_in_left); //为ViewSwitcher的组件隐藏过程设置动画 switcher.setInAnimation(this,R.anim.slide_out_right); //控制下一屏将要显示的GridView对应的Adapter ((GridView)switcher.getNextView()).setAdapter(adapter); //单击右边按钮,显示下一屏 switcher.showPrevious(); } } //该BaseAdapter负责为每屏显示的GridView提供列表项 private BaseAdapter adapter = new BaseAdapter() { @Override public View getView(int position, View convertView, ViewGroup parent) { View view =convertView; if(convertView == null) { //加载R.layout.labelicon布局文件 view = inflater.inflate(R.layout.labelicon, null); } //获取R.layout.labelicon布局文件中的ImageView组件,并为之设置图标 ImageView imageView = (ImageView) view.findViewById(R.id.imageView); imageView.setImageDrawable(getItem(position).drawable); //获取R.layout.labelicon布局文件中的TextView组件,并为之设置文本 TextView textView = (TextView) view.findViewById(R.id.textView); textView.setText(getItem(position).dataName); return view; } @Override public long getItemId(int position) { return position; } @Override public DataItem getItem(int position) { //根据screenNo计算第position个列表项的数据 return items.get(screenNo * NUMER_PER_SCREEN + position); } @Override public int getCount() { //如果已经到了最后一屏,且应用程序的数量不能整除NUMBER_PER_SCREEN if(screenNo == screenCount - 1 && items.size() % NUMER_PER_SCREEN != 0) { //最后一屏显示的程序数为应用程序的数量对NUMBER_PER_SCREEN求余 return items.size() % NUMER_PER_SCREEN; } //否则每屏显示的程序数量为NUMER_PER_SCREEN return NUMER_PER_SCREEN; } }; } 效果 Screenshot_20171020-151447.png 提示 也许你会对这个程序的一些代码感到疑惑,比如说这段代码。 View view =convertView; if(convertView == null) { //加载R.layout.labelicon布局文件 view = inflater.inflate(R.layout.labelicon, null); } 其实它只不过是ListView缓存的一种手段,这样在你快速滑动的时候可以防止内存溢出。 点击按钮会切换到另一个页面,这可不是跳转到另一Activity。以后我会写关于手势操作的文章,这样就可以通过手势来进行页面切换。 ImageSwitcher ImageSwitcher继承了ViewSwitcher,因此它具有与ViewSwitcher相同的特征:可以在切换View组件时使用动画效果。ImageSwitcher的操作很简单,只需要如下两步即可。 为ImageSwitcher提供一个ViewFactory,该ViewFactory生成的View组件必须是ImageView。 需要切换图片时,只要调用ImageSwitcher的setImageDrawable(Drawable drawable)、setImageResource(int resid)和setImageURI(Uri uri)方法更换图片即可。 代码示例 imageswitch.xml <?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:orientation="vertical" android:gravity="center_horizontal" > <!-- 定义一个GridView组件 --> <GridView android:id="@+id/grid01" android:layout_width="match_parent" android:layout_height="wrap_content" android:horizontalSpacing="2dp" android:verticalSpacing="2dp" android:numColumns="4" android:gravity="center" /> <!-- 定义一个ImageSwitcher --> <ImageSwitcher android:id="@+id/switcher" android:layout_width="300dp" android:layout_height="300dp" android:layout_gravity="center_horizontal" android:inAnimation="@android:anim/fade_in" android:outAnimation="@android:anim/fade_out" /> </LinearLayout> MainActivity.java public class MainActivity extends Activity { int []imageIds = new int[] { R.drawable.baxianhua,R.drawable.dengta,R.drawable.ic_launcher,R.drawable.juhua, R.drawable.kaola,R.drawable.qie,R.drawable.shamo,R.drawable.shuimo, R.drawable.yujinx,R.drawable.baxianhua,R.drawable.dengta,R.drawable.ic_launcher, R.drawable.juhua,R.drawable.kaola,R.drawable.qie,R.drawable.shamo }; ImageSwitcher switcher; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.imageswitch); List<Map<String,Object>> listItems = new ArrayList<Map<String,Object>>(); for (int i = 0; i < imageIds.length; i++) { Map<String,Object> listItem = new HashMap<String, Object>(); listItem.put("image", imageIds[i]); listItems.add(listItem); } //获取显示图片的ImageSwitcher switcher = (ImageSwitcher) findViewById(R.id.switcher); //为ImageSwitcher设置图片切换的动画效果 switcher.setFactory(new ViewFactory() { @Override public View makeView() { //创建ImageView对象 ImageView imageView = new ImageView(MainActivity.this); imageView.setScaleType(ScaleType.FIT_CENTER); imageView.setLayoutParams(new ImageSwitcher.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); return imageView; } }); SimpleAdapter simpleAdapter = new SimpleAdapter(this, listItems, R.layout.cell, new String[] {"image"}, new int[] {R.id.image1}); GridView grid = (GridView) findViewById(R.id.grid01); grid.setAdapter(simpleAdapter); //添加列表项被选中的监听器 grid.setOnItemSelectedListener(new GridView.OnItemSelectedListener() { @Override public void onNothingSelected(AdapterView<?> parent) { } @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { //显示被选中的图片 switcher.setImageResource(imageIds[position]); } }); grid.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //显示被选中的图片 switcher.setImageResource(imageIds[position]); } }); } } 效果 Screenshot_20171020-161723.png 提示 TextSwitcher组件 TextSwitcher组件继承了ViewSwitcher组件,与上面的ImageSwitcher组件的用法相似,唯一不同的是TextSwitcher所需的ViewFactory的makeView()方法必须返回一个TextView组件。 代码示例 textswitcher.xml <?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" > <!-- 定义一个TextSwitcher,并指定了文本切换时的动画效果 --> <TextSwitcher android:id="@+id/textSwitcher" android:layout_width="match_parent" android:layout_height="wrap_content" android:inAnimation="@android:anim/slide_in_left" android:outAnimation="@android:anim/slide_out_right" android:onClick="next" /> </LinearLayout> MainActivity.java public class MainActivity extends Activity { TextSwitcher textSwitcher; String[] strs = new String[] { "水浒传","三国演义","红楼梦","西游记" }; int curStr; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.textswitcher); textSwitcher = (TextSwitcher) findViewById(R.id.textSwitcher); textSwitcher.setFactory(new ViewFactory() { @Override public View makeView() { TextView tv = new TextView(MainActivity.this); tv.setTextSize(40); tv.setTextColor(Color.MAGENTA); return tv; } }); //调用next方法显示一个字符串 next(null); } public void next(View v) { textSwitcher.setText(strs[curStr++ % strs.length]); } } 效果 Screenshot_20171023-092903.png 点击文本会出现切换效果 提示 TextSwitcher与TextView的功能有点相似,它们都可用于显示文本内容,区别在于TextSwitcher的效果更炫,它可以指定文本切换时的动画效果。 ViewFlipper组件 ViewFlipper组件继承了ViewAnimator,它可以调用addView(View v)方法添加多个组件,一旦向ViewFlipper中添加多个组件之后,ViewFlipper就可使动画控制多个组件之间的切换效果。它与前边介绍的AdapterViewFlipper有较大的相似性,区别就是ViewFlipper需要开发者通过addView(View v)添加多个View,而AdapterViewFlipper只要传入一个Adapter,Adapter将会负责提供多个View。 代码示例 viewflipper.xml <?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" > <ViewFlipper android:id="@+id/details" android:layout_width="match_parent" android:layout_height="match_parent" android:flipInterval="1000" > <ImageView android:src="@drawable/baxianhua" android:layout_width="match_parent" android:layout_height="wrap_content" /> <ImageView android:src="@drawable/dengta" android:layout_width="match_parent" android:layout_height="wrap_content" /> <ImageView android:src="@drawable/juhua" android:layout_width="match_parent" android:layout_height="wrap_content" /> </ViewFlipper> <Button android:text="<" android:onClick="prev" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" /> <Button android:text="自动播放" android:onClick="auto" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerInParent="true" /> <Button android:text=">" android:onClick="next" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" /> </RelativeLayout> MainAcitivity.java public class MainActivity extends Activity { private ViewFlipper viewFlipper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.viewflipper); viewFlipper = (ViewFlipper) findViewById(R.id.details); } public void prev(View v) { viewFlipper.setInAnimation(this, R.anim.slide_in_right); viewFlipper.setOutAnimation(this, R.anim.slide_out_left); // 显示上一个组件 viewFlipper.showPrevious(); // 停止自动播放 viewFlipper.stopFlipping(); } public void next(View v) { viewFlipper.setInAnimation(this, R.anim.slide_in_left); viewFlipper.setOutAnimation(this, R.anim.slide_out_right); // 显示下一个组件 viewFlipper.showNext(); // 停止自动播放 viewFlipper.stopFlipping(); } public void auto(View v) { viewFlipper.setInAnimation(this, R.anim.slide_in_left); viewFlipper.setOutAnimation(this, R.anim.slide_out_right); //开始自动播放 viewFlipper.startFlipping(); } } 效果 Screenshot_20171023-100803.png 提示 ViewFlipper可以指定与AdapterViewFlipper相同的XML属性。

优秀的个人博客,低调大师

UI组件-AdapterView及其子类

前言 只要自己变优秀了,其他的事情才会跟着好起来。 ListView组件 ListView是手机系统中使用非常广泛的一种组件,它以垂直列表的形式显示所有列表项。接下来介绍几种创建ListView的方法。 代码示例 使用数组创建ListView listview.xml <?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:orientation="vertical" > <!-- 直接使用数组资源给出列表项 --> <!-- 设置使用红色的分隔条 --> <ListView android:layout_width="match_parent" android:layout_height="wrap_content" android:entries="@array/books" android:divider="#f00" android:dividerHeight="2px" /> </LinearLayout> arrays.xml <?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="books"> <item>西游记</item> <item>水浒传</item> <item>三国演义</item> <item>红楼梦</item> </string-array> </resources> 使用ArrayAdapter创建ListView listview2.xml <?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:orientation="vertical" > <!-- 设置红色分隔条 --> <ListView android:id="@+id/list1" android:layout_width="match_parent" android:layout_height="wrap_content" android:divider="#f00" android:dividerHeight="2px" /> <!-- 设置绿色分隔条 --> <ListView android:id="@+id/list2" android:layout_width="match_parent" android:layout_height="wrap_content" android:divider="#0f0" android:dividerHeight="2px" /> </LinearLayout> array_item.xml <?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="24dp" android:padding="10px" android:shadowColor="#f0f" android:shadowDx="4" android:shadowDy="4" android:shadowRadius="2"/> MainActivity.java public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.listview2); ListView list1 = (ListView) findViewById(R.id.list1); //定义一个数组 String []books = new String[] {"三国演义","红楼梦","西游记","水浒传"}; //将数组包装为ArrayAdapter ArrayAdapter<String> adapter1 = new ArrayAdapter<String>(this, R.layout.array_item, books); //为ListView设置Adapter list1.setAdapter(adapter1); ListView list2 = (ListView) findViewById(R.id.list2); //定义一个数组 String []names = new String[] {"孙悟空","猪八戒","沙和尚","唐僧"}; //将数组包装为ArrayAdapter ArrayAdapter<String> adapter2 = new ArrayAdapter<String>(this, R.layout.array_item, names); //为ListView设置Adapter list2.setAdapter(adapter2); } } 使用SimpleAdapter创建ListView listview3.xml、 <?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:orientation="horizontal" > <!-- 定义一个ListView --> <ListView android:id="@+id/mylist" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> simple_item.xml <?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="wrap_content" android:orientation="horizontal" > <!-- 定义一个ImageView,作为列表项的一部分 --> <ImageView android:id="@+id/header" android:scaleType="fitXY" android:layout_width="40dp" android:layout_height="40dp" android:paddingLeft="10dp" /> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" > <!-- 定义一个TextView,作为列表项的一部分 --> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20dp" android:textColor="#f0f" android:paddingLeft="10dp" /> <!-- 定义一个TextView,作为列表项的一部分 --> <TextView android:id="@+id/desc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14dp" android:paddingLeft="10dp" /> </LinearLayout> </LinearLayout> MainActivity.java public class MainActivity extends Activity { private String[] names = new String[] {"考拉","郁金香","企鹅","水母"}; private String[] descs = new String[] {"一种可爱的动物","一种美丽的花朵","一种生活在南极的动物","一种生活在海里的神奇生物"}; private int[] imageIds = new int[] {R.drawable.kaola,R.drawable.yujinx,R.drawable.qie,R.drawable.shuimo}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.listview3); //创建一个List集合,List集合的元素是Map List<Map<String,Object>> listItems = new ArrayList<Map<String,Object>>(); for(int i = 0; i < names.length; i++) { Map<String, Object> listItem = new HashMap<String, Object>(); listItem.put("header", imageIds[i]); listItem.put("name", names[i]); listItem.put("desc", descs[i]); listItems.add(listItem); } //创建一个SimpleAdapter SimpleAdapter simpleAdapter = new SimpleAdapter(this, listItems, R.layout.simple_item, new String[] {"name","header","desc"}, new int[] {R.id.name,R.id.header,R.id.desc}); ListView list = (ListView) findViewById(R.id.mylist); //为ListView设置Adapter list.setAdapter(simpleAdapter); } } 使用BaseAdapter创建ListView listview4.xml <?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:orientation="vertical" > <ListView android:id="@+id/myList" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> MainActivity.java public class MainActivity extends Activity { ListView myList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.listview4); myList = (ListView) findViewById(R.id.myList); BaseAdapter adapter = new BaseAdapter() { //重写该方法,该方法返回的View将作为列表框 @Override public View getView(int position, View convertView, ViewGroup parent) { //创建一个LinearLayout,并向其中添加两个组件 LinearLayout line = new LinearLayout(MainActivity.this); line.setOrientation(0); ImageView image = new ImageView(MainActivity.this); image.setImageResource(R.drawable.ic_launcher); TextView text = new TextView(MainActivity.this); text.setText("第" + (position + 1) + "个列表项"); text.setTextSize(20); text.setTextColor(Color.RED); line.addView(image); line.addView(text); return line; } @Override public long getItemId(int position) { return position; } @Override public Object getItem(int position) { return null; } @Override public int getCount() { //指定一共包含40个列表项 return 40; } }; myList.setAdapter(adapter); } } 基于ListActivity实现列表 listactivity.xml <?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" /> MainActivity.java public class MainActivity extends ListActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //无需使用布局文件 String[] names = {"西游记","红楼梦","三国演义","水浒传"}; //创建ArrayAdapter对象 ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.listactivity, names); //设置该窗口显示列表 setListAdapter(adapter); } } 效果 使用数组创建的ListView Screenshot_1508382099.png 使用ArrayAdapter创建的ListView Screenshot_1508383040.png 使用SimpleAdapter创建的ListView Screenshot_1508388930.png 使用BaseAdapter创建的ListView Screenshot_1508389647.png 基于ListActivity实现的列表 Screenshot_1508390424.png 提示 当列表项很多时,为了防止内存溢出,可以使用ListView的andriod:scrollingCache属性来绘制缓冲,同时还有别的方法。以后将会介绍。 下面我来说说上述几个Adapter的区别。 ArrayAdapter:简单、易用的Adapter,通常用于将数组或List集合的多个值包装成多个列表项。 SimpleAdapter:并不简单、功能强大的Adapter,可用于将List集合的多个对象包装成多个列表项。 BaseAdapter:通常用于被扩展。扩展BaseAdapter可以对各列表项进行最大限度的定制。我比较喜欢用这个Adapter,使用这个Adapter需要重写如下四个方法。 getCount():该方法的返回值控制该Adapter将会包含多少个列表项。 getItem(int position):该方法的返回值决定第position处的列表项的内容。 getItemId(int position):该方法的返回值决定第position处的列表项的ID。 getView(int position,View convertView,ViewGroup parent):该方法的返回值决定第position处的列表项组件。 其中最重要的第1个和第4个方法。 AutoCompleteTextView组件 自动完成文本框(AutoCompeletTextView)从EditText派生而出,实际上它也是一个文本编辑框,但它比普通编辑框多了一个功能:当用户输入一定的字符之后,自动完成文本框会显示一个下拉菜单,供用户选择,当用户选择某个菜单项之后,AutoCompleteTextView按用户选择自动填写该文本框。 代码示例 autocompletetextview.xml <?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:orientation="vertical" > <!-- 定义一个自动完成文本框,指定输入一个字符后进行提示 --> <AutoCompleteTextView android:id="@+id/auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:completionHint="请选择您喜欢的图书" android:completionThreshold="1" /> <!-- 定义一个MultiAutoCompleteTextView组件 --> <MultiAutoCompleteTextView android:id="@+id/mauto" android:layout_width="match_parent" android:layout_height="wrap_content" android:completionThreshold="1" /> </LinearLayout> MainActivity.java public class MainActivity extends Activity { AutoCompleteTextView actv; MultiAutoCompleteTextView mauto; //定义字符串数组,作为提示文本 String[] books = new String[] { "西游记", "水浒传", "三国演义", "水浒传" }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.autocompletetextview); //创建一个ArrayAdapter,封装数组 ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, books); actv = (AutoCompleteTextView) findViewById(R.id.auto); //设置Adapter actv.setAdapter(adapter); mauto = (MultiAutoCompleteTextView) findViewById(R.id.mauto); //设置Adapter mauto.setAdapter(adapter); //为MultiAutoCompleteTextView设置分隔符 mauto.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer()); } } 效果 Screenshot_1508393517.png 提示 AutoCompleteTextView与MultiAutoCompleteTextView的区别在于MultiAutoCompleteTextView允许输入多个提示项,多个提示项以分隔符分隔。 android:comletionThreshold属性,设置用户至少输入几个字符才会显示提示。 GridView组件 网格视图(GridView)和ListView有共同的父类,它们的唯一区别在于ListView只显示一列,而GridView可以显示多列。另外,ListView相当于一种特殊的GridView,如果GridView只显示一列,那么该GridView就变成了ListView。 与ListView类似的是,GridView也需要Adapter来提供显示的诗数据,可以通过ArrayAdapter、SimpleAdapter、BaseAdapter来创建Adapter,用法基本一致。 代码示例 gridview.xml <?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:orientation="vertical" android:gravity="center_horizontal" > <!-- 定义一个GridView组件 --> <GridView android:id="@+id/grid01" android:layout_width="match_parent" android:layout_height="wrap_content" android:horizontalSpacing="1pt" android:verticalSpacing="1pt" android:numColumns="4" android:gravity="center" /> <!-- 定义一个ImageView --> <ImageView android:id="@+id/imageView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="2dp" android:layout_gravity="center_horizontal" /> </LinearLayout> cell.xml <?xml version="1.0" encoding="utf-8"?> <ImageView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/image1" android:layout_width="70dp" android:layout_height="70dp" /> MainActivity.java public class MainActivity extends Activity { GridView grid; ImageView imageView; int[] imageIds = new int[] { R.drawable.baxianhua,R.drawable.dengta,R.drawable.ic_launcher,R.drawable.juhua, R.drawable.kaola,R.drawable.shamo,R.drawable.shuimo,R.drawable.yujinx, R.drawable.qie,R.drawable.shamo,R.drawable.shuimo,R.drawable.yujinx, R.drawable.baxianhua,R.drawable.dengta,R.drawable.ic_launcher,R.drawable.juhua }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.gridview); //创建一个List对象,List对象的元素是Map List<Map<String,Object>> listItems = new ArrayList<Map<String,Object>>(); for (int i = 0; i < imageIds.length; i++) { Map<String,Object> listItem = new HashMap<String, Object>(); listItem.put("image", imageIds[i]); listItems.add(listItem); } //获取显示图片的ImageView imageView = (ImageView) findViewById(R.id.imageView); //创建一个SimpleAdapter SimpleAdapter simpleAdapter = new SimpleAdapter(this, listItems, R.layout.cell, new String[] {"image"}, new int[] {R.id.image1}); grid = (GridView) findViewById(R.id.grid01); //为GridView设置Adapter grid.setAdapter(simpleAdapter); //添加列表项被选中的监听器 grid.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onNothingSelected(AdapterView<?> parent) { } @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { //显示当前被选中的图片 imageView.setImageResource(imageIds[position]); } }); //添加列表项被单击的监听器 grid.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //显示背单击的图片 imageView.setImageResource(imageIds[position]); } }); } } 效果 Screenshot_1508398206.png 提示 android:numColumns属性,设置列数。 android:horizontalSpacing属性,设置个元素之间的水平间距。 android:verticalSpacing属性,设置个元素之间的垂直间距。 ExpandableListView组件 可展开的列表组件(ExpandableListView)是ListView的子类,它在普通ListView的基础上进行了扩展,它把应用中的列表项分为几组,每组里又可包含多个列表项。 ExpandableListView所显示的列表项由ExpandableListAdapter提供。实现ExpandableListAdapter的方式有如下三种。 扩展BaseExpandableListAdapter实现ExpandableListAdapter。 使用SimpleExpandableListAdapter将两个List集合包装成ExpandableListAdapter。 使用SimpleCursorTreeAdapter将Cursor中的数据包装成SimpleCursorTreeAdapter。 代码示例 expandablelistview.xml <?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:orientation="vertical" > <ExpandableListView android:id="@+id/list" android:childDivider="#f00" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> MainActivity.java public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.expandablelistview); //创建一个ExpandableListAdapter对象 ExpandableListAdapter adapter = new BaseExpandableListAdapter() { int[] logos = new int[] { R.drawable.kaola, R.drawable.qie, R.drawable.shuimo }; private String[] armTypes = new String[] {"考拉","企鹅","水母"}; private String[][] arms = new String[][] { {"白考拉","红考拉","黑考拉"}, {"白企鹅","帝企鹅","黑企鹅"}, {"白水母","毒水母","黑水母"} }; @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } @Override public boolean hasStableIds() { return true; } //该方法决定每个组选项的外观 @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { LinearLayout ll = new LinearLayout(MainActivity.this); ll.setOrientation(0); ImageView logo = new ImageView(MainActivity.this); logo.setImageResource(logos[groupPosition]); logo.setLayoutParams(new LinearLayout.LayoutParams(100, 100)); ll.addView(logo); TextView textView = new TextView(MainActivity.this); textView.setText(getGroup(groupPosition).toString()); textView.setTextSize(20); ll.addView(textView); return ll; } @Override public long getGroupId(int groupPosition) { return groupPosition; } @Override public int getGroupCount() { return armTypes.length; } //获取指定组位置处的组数据 @Override public Object getGroup(int groupPosition) { return armTypes[groupPosition]; } @Override public int getChildrenCount(int groupPosition) { return arms[groupPosition].length; } private TextView geTextView() { AbsListView.LayoutParams lp = new AbsListView.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT,64); TextView textView = new TextView(MainActivity.this); textView.setLayoutParams(lp); textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT); textView.setPadding(36, 0, 0, 0); textView.setTextSize(20); return textView; } //该方法决定每个子选项的外观 @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { TextView textView = geTextView(); textView.setText(getChild(groupPosition, childPosition).toString()); return textView; } @Override public long getChildId(int groupPosition, int childPosition) { return childPosition; } //获取指定组位置、指定子列表项处的子列表项数据 @Override public Object getChild(int groupPosition, int childPosition) { return arms[groupPosition][childPosition]; } }; ExpandableListView expandListView = (ExpandableListView) findViewById(R.id.list); expandListView.setAdapter(adapter); } } 效果 Screenshot_20171020-093318.png 提示 上面使用BaseExpandableListAdapter来实现ExpandableListAdapter,当扩展BaseExpandableListAdapter时,关键是实现如下4个方法。 getGroupCount():该方法返回包含的组列表项的数量。 getGroupView():该方法返回的View对象将作为组列表项。 getChildrenCount():该方法返回特定组所包含的子列表项的数量。 getChildView():该方法返回的View对象将作为特定组,特定位置的子列表项。 Spinner组件 Spinner其实就是一个列表选择框,不过不是显示下拉列表,而是弹出一个菜单供用户选择。如果已经确定了Spinner的列表项,只要为Spinner指定android:entries属性即可;如果不确定列表项,需要在程序运行时动态决定Spinner的列表项,则需要用Adapter来为Spinner提供列表项。 代码示例 spinner.xml <?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:orientation="vertical" > <!-- 定义一个Spinner组件,指定显示该Spinner组件的数组 --> <Spinner android:layout_width="match_parent" android:layout_height="wrap_content" android:entries="@array/books" /> <Spinner android:id="@+id/spinner" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> MainActivity.java public class MainActivity extends Activity { Spinner spinner; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.spinner); //获取界面布局文件中的Spinner spinner = (Spinner) findViewById(R.id.spinner); String []arr = {"西游记","红楼梦","三国演义","水浒传"}; //创建ArrayAdapter对象 ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice,arr); //为Spinner设置Adapter spinner.setAdapter(adapter); } } 效果 Screenshot_20171020-100344.png 提示 第一个Spinner组件指定了android:entries属性,第二个Spinner组件没有指定android:entries属性,因此需要在Activity中为它设置Adapter。 AdapterViewFlipper组件 AdapterViewFlipper继承了AdapterViewAnimator,它也会显示Adapter提供的多个View组件,但它每次只能显示一个View组件,程序可通过showPrevious()和showNext()方法控制该组件显示上一个、下一个组件。它还有自动播放的功能。 代码示例 adapterviewanimator.xml <?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"> <AdapterViewFlipper android:id="@+id/flipper" android:layout_width="match_parent" android:layout_height="match_parent" android:flipInterval="5000" android:layout_alignParentTop="true" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentBottom="true" android:onClick="prev" android:text="上一个" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:onClick="next" android:text="下一个" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentBottom="true" android:onClick="auto" android:text="自动播放" /> </RelativeLayout> MainAvtivity.java public class MainActivity extends Activity { int[] imageIds = new int[] { R.drawable.baxianhua,R.drawable.dengta,R.drawable.juhua, R.drawable.kaola,R.drawable.qie,R.drawable.shamo,R.drawable.shuimo, R.drawable.yujinx }; private AdapterViewFlipper flipper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.adapterviewanimator); flipper = (AdapterViewFlipper) findViewById(R.id.flipper); //创建一个BaseAdapter对象 BaseAdapter adapter = new BaseAdapter() { @Override public View getView(int position, View convertView, ViewGroup parent) { //创建一个ImageView ImageView imageView = new ImageView(MainActivity.this); imageView.setImageResource(imageIds[position]); //设置ImageView的缩放类型 imageView.setScaleType(ScaleType.FIT_XY); //为ImageView设置布局参数 imageView.setLayoutParams(new ViewGroup.LayoutParams( LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT )); return imageView; } @Override public long getItemId(int position) { return position; } @Override public Object getItem(int position) { return imageIds[position]; } @Override public int getCount() { return imageIds.length; } }; flipper.setAdapter(adapter); } public void prev(View view) { //显示上一个组件 flipper.showPrevious(); //停止自动播放 flipper.stopFlipping(); } public void next(View view) { //显示上一个组件 flipper.showNext(); //停止自动播放 flipper.stopFlipping(); } public void auto(View view) { //开始自动播放 flipper.startFlipping(); } } 效果 Screenshot_20171020-103243.png 提示 android:animateFirstView属性,设置显示该组件的第一个View时是否使用动画。 android:inAnimation属性,设置组件显示时使用的动画。 android:loopViews属性,设置循环播放。 android:autoStart属性,设置是否自动播放。 android:flipInterval属性,设置自动播放的时间间隔。 StackView组件 StackView也是AdapterViewAnimator的子类,它用于显示Adapter提供的一系列View。StackView将会以“堆叠”的方式来显示多个列表项。 代码示例 stackview.xml <?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:orientation="horizontal" > <StackView android:id="@+id/stackview" android:layout_width="match_parent" android:layout_height="wrap_content" android:loopViews="true" /> <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="上一个" android:onClick="prev" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="下一个" android:onClick="next" /> </LinearLayout> </LinearLayout> MainActivity.java public class MainActivity extends Activity { private StackView stackView; int[] imageIds = new int[] { R.drawable.baxianhua,R.drawable.dengta,R.drawable.juhua, R.drawable.kaola,R.drawable.qie,R.drawable.shamo,R.drawable.shuimo, R.drawable.yujinx }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.stackview); stackView = (StackView) findViewById(R.id.stackview); //创建一个List对象,List对象的元素是Map List<Map<String,Object>> listItems = new ArrayList<Map<String,Object>>(); for (int i = 0; i < imageIds.length; i++) { Map<String, Object> listItem = new HashMap<String, Object>(); listItem.put("image", imageIds[i]); listItems.add(listItem); } //创建一个SimpleAdapter SimpleAdapter simpleAdapter = new SimpleAdapter(this, listItems, R.layout.cell, new String[] {"image"}, new int[] {R.id.image1}); stackView.setAdapter(simpleAdapter); } public void prev(View view) { //显示上一个组件 stackView.showPrevious(); } public void next(View view) { //显示下一个组件 stackView.showNext(); } } 效果 Screenshot_20171020-110029.png

优秀的个人博客,低调大师

UI组件-ImageView及其子类

前言 时间有限,追索生命的诚意和真实,比什么都重要。 ImageView组件 ImageView继承自View组件,它的主要功能是用于显示任何Drawable对象。 为了控制ImageView显示的图片,ImageView提供了下列方法。 setImageBitmap(Bitmap bm):使用Bitmap位图设置该ImageView显示的图片。 setImageDrawable(Drawable drawable):使用Drawable对象设置该ImageView显示的图片。 setImageResource(int resId):使用图片资源ID设置该ImageView显示的图片。 setImageURI(Uri uri):使用图片的URI设置该ImageView显示的图片。 示例代码 本例的图片浏览器不仅可以改变图片的透明度,还可以查看图片指定区域的细节。 main.xml <?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:orientation="vertical" > <!-- 定义三个按钮 --> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" > <Button android:id="@+id/plus" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="增大透明度" /> <Button android:id="@+id/minus" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="减小透明度" /> <Button android:id="@+id/next" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="下一张" /> </LinearLayout> <!-- 定义显示图片整体的ImageView --> <ImageView android:id="@+id/image1" android:layout_width="wrap_content" android:layout_height="360dp" android:src="@drawable/baxianhua" android:scaleType="fitCenter" /> <!-- 定义显示图片局部细节的ImageView --> <ImageView android:id="@+id/image2" android:layout_width="240dp" android:layout_height="240dp" android:background="#00f" android:layout_margin="10dp" /> </LinearLayout> MainActivity.java public class MainActivity extends Activity { //定义一个访问图片的数组 int []images = new int[] { R.drawable.baxianhua, R.drawable.dengta, R.drawable.juhua, R.drawable.kaola, R.drawable.qie, R.drawable.shamo, R.drawable.shuimo, R.drawable.yujinx, }; //定义默认显示的图片 int currentImg = 2; //定义图片的初始透明度 private int alpha = 255; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final Button minus = (Button) findViewById(R.id.minus); final Button plus = (Button) findViewById(R.id.plus); final Button next = (Button) findViewById(R.id.next); final ImageView image1 = (ImageView) findViewById(R.id.image1); final ImageView image2 = (ImageView) findViewById(R.id.image2); //定义查看下一张图片按钮的监听器 next.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //控制ImageView显示下一张图片 image1.setImageResource(images[++currentImg % images.length]); } }); //定义改变图片透明度的方法 View.OnClickListener listener = new OnClickListener() { @Override public void onClick(View v) { if(v == plus) { alpha -= 20; } if(v == minus) { alpha += 20; } if(alpha >= 255) { alpha = 255; } if(alpha <= 0) { alpha = 0; } //改变图片透明度 image1.setImageAlpha(alpha); } }; //为两个按钮添加监听器 plus.setOnClickListener(listener); minus.setOnClickListener(listener); image1.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { BitmapDrawable bitmapDrawable = (BitmapDrawable) image1.getDrawable(); //获取第一个图片显示框中的位图 Bitmap bitmap = bitmapDrawable.getBitmap(); //bitmap图片实际大小与第一个ImageView的缩放比例 double scale = 1.0 * bitmap.getHeight()/image1.getHeight(); //获取需要显示的图片的开始点 int x = (int)(event.getX() * scale); int y = (int)(event.getY() * scale); if(x + 240 > bitmap.getWidth()) { x = bitmap.getWidth() - 240; } if(y + 240 > bitmap.getHeight()) { y = bitmap.getHeight() - 240; } //显示图片的指定区域 image2.setImageBitmap(bitmap.createBitmap(bitmap, x, y, 240, 240)); image2.setImageAlpha(alpha); return false; } }); } } 效果 Screenshot_2017-10-18-16-07-20.png 提示 andriod:scaleType属性,设置所显示的图片如何缩放或移动以适应ImageView的大小。常用属性值如下。 matrix:使用matrix方式进行缩放。 fitXY:对图片横向、纵向独立缩放,使得该图片完全适应于该ImageView,图片的纵横比可能会改变。 fitStart:保持纵横比缩放图片,直到该图片能完全显示在ImageView中,缩放完成后将该图片放在ImageView的左上角。 fitCenter:保持纵横比缩放图片,直到该图片能完全显示在ImageView中,缩放完成后将该图片放在ImageView的中央。 fitEnd:保持纵横比缩放图片,直到该图片能完全显示在ImageView中,缩放完成后将该图片放在ImageView的右下角。 center:把图片放在ImageView的中间,但不进行任何缩放。 ImageButton组件 ImageButton与Button的区别在于,Button生成的按钮上显示文字,而ImageButton上则显示图片。ImageButton派生了一个ZoomButton,可以代表“放大”、“缩小”两个按钮。 代码示例 <?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:orientation="vertical" > <!-- 定义ZoomControls组件 --> <ZoomControls android:id="@+id/zoomControls1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" /> </LinearLayout> 效果 Screenshot_1508379554.png QuickContactBadge组件 QuickContactBadge继承了ImageView,因为它的本质是图片按钮,也可以通过andriod:src属性指定它显示的图片。额外增加的功能是该图片可以关联到手机中指定的联系人,当用户单击该图片时,系统将会打开相应联系人的联系方式界面。为了让QuickContactBadge与特定联系人关联,可以调用如下方法。 assignContactFromEmail(String emailAddapp\src\main\ress,boolean lazyLookup):将该图片关联到指定E-mail地址对应的联系人。 assignContactFromPhone(String phoneNumber,boolean lazyLookup):将该图片关联到指定电话号码对应的联系人。 assignContactUri(Uri contactUri):将该图片关联到特定Uri对应的联系人。 代码示例 contact.xml <?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"> <QuickContactBadge android:id="@+id/badge" android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/ic_launcher" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="16dp" android:text="halo" /> </LinearLayout> MainActivity.java public class MainActivity extends Activity { QuickContactBadge badge; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.contact); //获取QuickContactBadge组件 badge = (QuickContactBadge) findViewById(R.id.badge); //将QuickContactBadge组件与特定电话号码对应的联系人建立关联 badge.assignContactFromPhone("010-666666", false); } } 效果 Screenshot_1508380462.png 使用QuickContactBadge打开的特定联系人 Screenshot_1508380482.png

优秀的个人博客,低调大师

Android UI布局之FrameLayout

一个FrameLayout对象就好比一块屏幕上提前预定好的空白区域。然后能够填充一些元素到里边。例如说一张图片等。须要注意的是,全部的元素都被放置在FrameLayout区域最左边上的区域。并且无法为这些元素指定一个确切的位置。假设一个FrameLayout里边有多个子元素。那么后边的子元素的显示会重叠在前一个元素上。 实例:LayoutDemo 执行效果: 代码清单: 布局文件:frame_layout.xml <?xml version="1.0" encoding="utf-8"? > <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:id="@+id/photo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/bg" /> </FrameLayout> android:id 定义组件的id,在应用程序中。我们通过这个id就能够訪问到定义的这个元素。 android:layout_width="match_parent" 和android:layout_height="match_parent" 表示FrameLayout布局能够在x轴方向和y轴方向填充满父容器的空间。 android:layout_width="wrap_content" 和android:layout_height+"wrap_content" 表示ImageView元素的长和宽仅仅须要将bg.jpg包裹起来就可以,并不须要填充满父容器。 Java源码文件:FrameLayoutActivity.java package com.rainsong.layoutdemo; import android.app.Activity; import android.os.Bundle; public class FrameLayoutActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.frame_layout); } } 本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5245561.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android UI开发第二十三篇——分享书架UI实现

android中有很多的电子书阅读应用,应用中都仿真了书架的实现,这里也分享一篇读书应用的书架实现: java: public class ShelvesView extends GridView { private Bitmap mShelfBackground; private int mShelfWidth; private int mShelfHeight; private Bitmap mWebLeft; private Bitmap mWebRight; private int mWebRightWidth; public ShelvesView(Context context) { super(context); init(context); } public ShelvesView(Context context, AttributeSet attrs) { super(context, attrs); load(context, attrs, 0); init(context); } public ShelvesView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); load(context, attrs, defStyle); init(context); } private void load(Context context, AttributeSet attrs, int defStyle) { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ShelvesView, defStyle, 0); final Resources resources = getResources(); final int background = a.getResourceId(R.styleable.ShelvesView_shelfBackground, 0); final Bitmap shelfBackground = BitmapFactory.decodeResource(resources, background); if (shelfBackground != null) { mShelfWidth = shelfBackground.getWidth(); mShelfHeight = shelfBackground.getHeight(); mShelfBackground = shelfBackground; } mWebLeft = BitmapFactory.decodeResource(resources, R.drawable.web_left); final Bitmap webRight = BitmapFactory.decodeResource(resources, R.drawable.web_right); mWebRightWidth = webRight.getWidth(); mWebRight = webRight; a.recycle(); } private void init(Context context) { StateListDrawable drawable = new StateListDrawable(); SpotlightDrawable start = new SpotlightDrawable(context, this); start.disableOffset(); SpotlightDrawable end = new SpotlightDrawable(context, this, R.drawable.spotlight_blue); end.disableOffset(); TransitionDrawable transition = new TransitionDrawable(start, end); drawable.addState(new int[] { android.R.attr.state_pressed }, transition); final SpotlightDrawable normal = new SpotlightDrawable(context, this); drawable.addState(new int[] { }, normal); normal.setParent(drawable); transition.setParent(drawable); setSelector(drawable); setDrawSelectorOnTop(false); } @Override protected void dispatchDraw(Canvas canvas) { final int count = getChildCount(); final int top = count > 0 ? getChildAt(0).getTop() : 0; final int shelfWidth = mShelfWidth; final int shelfHeight = mShelfHeight; final int width = getWidth(); final int height = getHeight(); final Bitmap background = mShelfBackground; for (int x = 0; x < width; x += shelfWidth) { for (int y = top; y < height; y += shelfHeight) { canvas.drawBitmap(background, x, y, null); } } if (count == 0) { canvas.drawBitmap(mWebLeft, 0.0f, top + 1, null); canvas.drawBitmap(mWebRight, width - mWebRightWidth, top + shelfHeight + 1, null); } super.dispatchDraw(canvas); } @Override public void setPressed(boolean pressed) { super.setPressed(pressed); final Drawable current = getSelector().getCurrent(); if (current instanceof TransitionDrawable) { if (pressed) { ((TransitionDrawable) current).startTransition( ViewConfiguration.getLongPressTimeout()); } else { ((TransitionDrawable) current).resetTransition(); } } } } 代码:http://download.csdn.net/detail/xyz_lmn/4698124 本文转自xyz_lmn51CTO博客,原文链接:http://blog.51cto.com/xyzlmn/1230767,如需转载请自行联系原作者

优秀的个人博客,低调大师

前端 UI 框架 Svelte 4 发布

距离 Svelte 3 发布已经过去了四年多的时间,经过几个月的筹备,Svelte 4 稳定版本于今天正式发布。 新版本改进了性能、优化了开发者体验,并大改了网站。Svelte 4 主要是一个维护版本,它为下一代的 Svelte 发布奠定了基础。 性能 这个版本使 hydration 代码更小更快。为了看到其影响,SvelteKit 用户可以通过检查.svelte-kit/output/client/_app/immutable/nodes文件夹来看到其编译后的输出尺寸缩小。例如,在kit.svelte.dev 上,整个网站生成的 JS 大小减少了 12.7%。 Svelte 4 将 Svelte 包的大小减少了近 75%,这意味着在npm install上的等待时间减少了。对于第一次在 learn.svelte.dev 上加载交互式学习体验的用户、Svelte REPL 的用户以及网络条件有限的用户来说,这一改进将尤为明显。剩下的大部分软件包大小是对 eslint 的支持,这就需要发布一个 CJS 构建,一旦 eslint 重写完成,Svelte的软件包大小可以再下降 50% 以上。 Svelte 中依赖的数量已经从 61 个大大减少到 16 个。这意味着用户下载速度更快,也更不容易受到供应链攻击的影响。 开发者体验 Svelte 4 使 Svelte 的创作体验更加直观和一致: |local现在是转换的默认值,以避免动画阻碍页面转换,预处理程序现在更容易编写,多项修正使 CSP 更容易设置和使用。 对于 Web 组件的用户来说,最大的变化是对你使用 Svelte 编写自定义元素的方式进行了全面修改。通过改变它们的生成方式,可以消除了一大类错误和不一致的地方。 最后,还做了几项改进 IDE 编写的体验:“cmd + 点击” svelte 模块现在可以带你到实现,而不是.d.ts文件。 从svelte/internal导入的文件现在被隐藏,不会干扰自动补全建议,自动导入现在更可靠。 更新了网站、文档和教程 官方 svelte.dev 网站已经进行了大改。它现在被分割成多个页面,并改进了导航、更新了 TypeScript 文档、黑暗模式和增强的 REPL。SvelteKit 网站也在进行更新,以与之匹配。还更新了所有的教程链接,以指向新的 learn.svelte.dev。旧的教程仍然适用于 Safari 16.3 及以前的用户。 更多详情可查看:https://github.com/sveltejs/svelte/releases/tag/svelte%404.0.0

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册