android纯代码构造的页面,【Android】纯代码创建页面布局(含异步加载图片)

开发环境:macOS 10.12 + Android Studio 2.2,MinSDK Android 5.1

先看看总体效果

63d4db744f6162275b208da606fb09d3.png

本示例是基于Fragment进行的,直接上代码:

【界面结构】

在 Fragment 中,采用 ScrollView + LinearLayout 实现。

1

2 xmlns:tools="http://schemas.android.com/tools"

3 android:layout_width="match_parent"

4 android:layout_height="match_parent"

5 android:scrollbars="vertical"

6 tools:context=".Fragment.HomeFrg">

7

9 android:layout_width="match_parent"

10 android:layout_height="match_parent"

11 android:orientation="vertical"

12 android:divider="@drawable/sep_home"

13 android:showDividers="middle" />

14

顺便说一句,显示列表中的分割线,采用自身的divider来实现,实现方式见上述代码中的第12、13行。

分割线采用 drawable 的 shape,注意:shape 中一定要添加 solid 和 size,并且 solid 的颜色必须定义,哪怕是透明的也要定义。

项目结构如下:

d18eb7cbfd76c56b77e37febefc9a647.png

背景颜色的定义,在 values/colors 中实现,如下所示:

1 #EEEEEE

整个 divider 的代码如下:

1 <?xml version="1.0" encoding="utf-8"?>

2

3

4

5

【代码结构】

新建 java 的类库,名为:TestImage.java,主要是结合缓存实现图片的异步加载(线程池方式),代码如下:

1 importandroid.graphics.drawable.Drawable;2 importandroid.os.Handler;3

4 importjava.lang.ref.SoftReference;5 importjava.net.URL;6 importjava.util.HashMap;7 importjava.util.Map;8 importjava.util.concurrent.ExecutorService;9 importjava.util.concurrent.Executors;10

11 public classTestImage {12 //为了加快速度,在内存中开启缓存13 //主要应用于重复图片较多时,或者同一个图片要多次被访问,比如在ListView时来回滚动

14 public Map> imageCache = new HashMap>();15

16 //固定 10 个线程来执行任务

17 private ExecutorService _exeService = Executors.newFixedThreadPool(10);18 private final Handler _handler = newHandler();19

20 public Drawable getImage(final String url, finalCallback callback) {21

22 //缓存中存在就用缓存中的图片

23 if(imageCache.containsKey(url)) {24 SoftReference softReference =imageCache.get(url);25

26 if (softReference.get() != null) {27 returnsoftReference.get();28 }29 }30

31 //缓存中没有图片,就从网络中获取图片,同时,存入缓存

32 _exeService.submit(newRunnable() {33

34 @Override35 public voidrun() {36 final Drawable drawable =getImage(url);37 imageCache.put(url, new SoftReference(drawable));38

39 _handler.post(newRunnable() {40

41 @Override42 public voidrun() {43 callback.imageLoaded(drawable);44 }45 });46 }47 });48

49 return null;50 }51

52 //从网络中获取图片

53 protectedDrawable getImage(String url) {54 Drawable drawable = null;55

56 try{57 drawable = Drawable.createFromStream(new URL(url).openStream(), "img.png");58 } catch(Exception e) {59 e.printStackTrace();60 }61

62 returndrawable;63 }64

65 //回调方法

66 public interfaceCallback {67 voidimageLoaded(Drawable drawable);68 }69 }

类库建立好了之后,在 Fragment 的后台代码中进行调用(含代码创建页面布局),代码如下:

1 public class HomeFrg extendsFragment {2

3 privateLinearLayout _layout;4 //private TestImage _testImage = new TestImage();

5

6 publicHomeFrg() {7 //Required empty public constructor

8 }9

10 @Override11 publicView onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {13 View view = inflater.inflate(R.layout.frg_home, container, false);14 initView(view);15

16 //Inflate the layout for this fragment

17 returnview;18 }19

20 private voidinitView(View view) {21 _layout =(LinearLayout) view.findViewById(R.id.frg_home);22

23 for (int i = 0; i < 3; i++) {24 initCell(view);25 }26 }27

28 private voidinitCell(View view) {29 Context self = this.getContext();30

31 //创建单个的单元格的容器(RelativeLayout)

32 RelativeLayout.LayoutParams layoutWrapper = newRelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);33 RelativeLayout wrapper = newRelativeLayout(self);34 wrapper.setBackgroundColor(Helper.getColor(self, R.color.colorWhite));35 wrapper.setPadding(0, 30, 0, 30);36 _layout.addView(wrapper, layoutWrapper);37

38 //创建封面图片(ImageView)

39 RelativeLayout.LayoutParams layoutCover = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 600);40 ImageView imgCover = newImageView(self);41 int idCover =view.generateViewId();42 imgCover.setId(idCover);43 //异步加载网络图片(图片URL为测试图片)

44 loadImage("http://pic9.nipic.com/20100904/4845745_195609329636_2.jpg", imgCover);45 imgCover.setScaleType(ImageView.ScaleType.CENTER_CROP);46 imgCover.setPadding(20, 0, 20, 0);47 wrapper.addView(imgCover, layoutCover);48

49 //创建标题(TextView)

50 RelativeLayout.LayoutParams layoutTitle = newRelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);51 layoutTitle.setMargins(20, 0, 20, 0);52 layoutTitle.addRule(RelativeLayout.BELOW, idCover);53 TextView txtTitle = newTextView(self);54 int idTitle =view.generateViewId();55 txtTitle.setId(idTitle);56 txtTitle.setText("标题内容标题内容标题内容标题内容标题内容标题内容");57 txtTitle.setTextSize(20);58 //标题单行显示,多余的字符用省略号代替(包括以下两行)

59 txtTitle.setEllipsize(TextUtils.TruncateAt.END);60 txtTitle.setSingleLine();61 txtTitle.setTextColor(Helper.getColor(self, R.color.colorBlack));62 wrapper.addView(txtTitle, layoutTitle);63

64 //创建作者(TextView)

65 RelativeLayout.LayoutParams layoutAuthor = newRelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);66 layoutAuthor.setMargins(20, 0, 20, 0);67 layoutAuthor.addRule(RelativeLayout.BELOW, idTitle);68 TextView txtAuthor = newTextView(self);69 int idAuthor =view.generateViewId();70 txtAuthor.setId(idAuthor);71 txtAuthor.setText("作者名称");72 txtAuthor.setTextColor(Helper.getColor(self, R.color.colorBlack));73 wrapper.addView(txtAuthor, layoutAuthor);74

75 //创建日期(TextView)

76 RelativeLayout.LayoutParams layoutTime = newRelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);77 layoutTime.setMargins(20, 0, 20, 0);78 layoutTime.addRule(RelativeLayout.BELOW, idAuthor);79 TextView txtTime = newTextView(self);80 txtTime.setText("2016年9月22日 16:33");81 wrapper.addView(txtTime, layoutTime);82 }83

84 //再次封装 TestImage,实现异步加载,方便页面内调用

85 private void loadImage(String url, finalImageView imageView) {86 Drawable imgCache = new TestImage().getImage(url, newTestImage.Callback() {87

88 @Override89 public voidimageLoaded(Drawable drawable) {90 imageView.setImageDrawable(drawable);91 }92 });93

94 if (imgCache != null) {95 imageView.setImageDrawable(imgCache);96 }97 }98 }

至此,所有功能实现完毕。

【特别说明】

上述代码在创建布局时,如果碰到最终效果,多个控件(包括 ImageView 和 TextView)重叠时,那是由于 RelativeLayout 的布局的特殊性,需要声明几个关键的东西:

1、声明 LayoutParams layout

2、控件.setId(view.generateViewId())

3、layout.addRule(RelativeLayout.BELOW, 上述 generateViewId() 所产生的 Id)

注意以上三点,即可在 RelativeLayout 中,将各个控件依次分开排列布局。同时,可通过 layout.setMargins 或 控件.setPadding 进行各处留白距离的微调。

原文:http://www.cnblogs.com/jacksonwj/p/5930161.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值