安卓开发使用定制的ArrayAdapter制作ListView的Items
背景介绍
对于现实世界中的商业移动应用来说,Android的ListView默认的界面外观不是非常有吸引力。它只是使用了内部的TextView控件,在每个ListView的行(Row)里面传递了一个简单的字符串而已。大多数应用,你会想要创建出富含图形界面和呈现给用户视觉体验良好的应用。幸运地是,ListView 是一个非常强大的控件,由于有可定制的item 布局的帮助,它可以被定制从而轻松地适应你的需求。在本文中,我将向你展示怎样创建一个定制的ListView Item(有图标,自定义的header布局)以及怎样使用定制的ArrayAdapter将他们联系起来。我也会向你展示一些性能优化的小方法来优化你的ListView控件的内存占用。下面用一个例子来展示:
一、项目布局
在Eclipse中,创建一个新的Android项目,使用默认的Activity和main.xml布局文件。在main.xml文件中,声明一个ListView控件。
main.xml文件:
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout
3 xmlns:android=http://schemas.android.com/apk/res/android
4 android:orientation="vertical"
5 android:layout_width="fill_parent"
6 android:layout_height="fill_parent"
7 android:background="#FFFFFF">
8
9 <ListView
10 android:id="@+id/listView1"
11 android:layout_width="fill_parent"
12 android:layout_height="fill_parent" />
13 </LinearLayout>
上面的代码,使用了简单的线性布局方式,内部垂直排列。声明了一个ListView,占据整个父容器,他的android.layout_width和android.layout_width的属性都为fill_parent。ListView有一个唯一的id:listView1,在MainActivity中将用来引用ListView控件。
为了创建定制的header,先在你的工程中创建一个新的xml布局文件:listview_header_row.xml,在里面声明一个TextView控件,属性值见下面的代码。将会创建出一个白色字体,蓝色背景的header。
1 listview_header_row.xml文件:
2 <?xml version="1.0" encoding="utf-8"?>
3 <LinearLayout
4 xmlns:android="http://schemas.android.com/apk/res/android"
5 android:orientation="horizontal"
6 android:layout_width="fill_parent"
7 android:layout_height="fill_parent">
8
9 <TextView android:id="@+id/txtHeader"
10 android:layout_width="fill_parent"
11 android:layout_height="fill_parent"
12 android:gravity="center_vertical"
13 android:layout_alignParentTop="true"
14 android:layout_alignParentBottom="true"
15 android:textStyle="bold"
16 android:textSize="22dp"
17 android:textColor="#FFFFFF"
18 android:padding="10dp"
19 android:text="Weather Photos"
20 android:background="#336699" />
21
22 </LinearLayout>
为了创建定制的ListView的行样式,先在你的工程中创建另一个xml布局文件:listview_item_row.xml。Android 会将这个文件的内容传递给每个ListView的item,你将可以自由的声明任何你想添加进里面的控件。本文中,我使用了一个ImageView来显示天气图标和一个TextView来显示该条item的主题。下面是listview_item_row.xml文件的代码:
1 listview_item_row.xml文件:
2 <?xml version="1.0" encoding="utf-8"?>
3 <LinearLayout
4 xmlns:android="http://schemas.android.com/apk/res/android"
5 android:orientation="horizontal"
6 android:layout_width="fill_parent"
7 android:layout_height="fill_parent"
8 android:padding="10dp">
9
10 <ImageView android:id="@+id/imgIcon"
11 android:layout_width="wrap_content"
12 android:layout_height="fill_parent"
13 android:gravity="center_vertical"
14 android:layout_alignParentTop="true"
15 android:layout_alignParentBottom="true"
16 android:layout_marginRight="15dp"
17 android:layout_marginTop="5dp"
18 android:layout_marginBottom="5dp" />
19
20 <TextView android:id="@+id/txtTitle"
21 android:layout_width="fill_parent"
22 android:layout_height="fill_parent"
23 android:gravity="center_vertical"
24 android:layout_alignParentTop="true"
25 android:layout_alignParentBottom="true"
26 android:textStyle="bold"
27 android:textSize="22dp"
28 android:textColor="#000000"
29 android:layout_marginTop="5dp"
30 android:layout_marginBottom="5dp" />
31
32 </LinearLayout>
本文中,我下载了一些32 X 32像素的PNG格式的图标。如果你愿意,你也可以使用你自己的图标。准备好你的图标,放到你工程的drawable-mdpi文件目录下。接下来,在工程中新建一个java类,命名为Weather.java,这个类将用于创建一个定制的ArrayAdapter来绑定对象到ListView中。下面是Weather.java文件的代码,它有两个简单的属性icon和title,一个普通的构造函数用于初始化属性。
二、项目程序开发
为了方便大家理解,我将程序结构流程画出来:
图3. 重要对象关系结构
1 Weather.java文件:
2 public class Weather {
3 public int icon;
4 public String title;
5 public Weather(){
6 super();
7 }
8
9 public Weather(int icon, String title) {
10 super();
11 this.icon = icon;
12 this.title = title;
13 }
14 }
注意,上面listview_item_row.xml文件有两个View,对应于Weather类的两个属性。Weather类的属性值将被显示到这两个View中。为了将这两个View连接起来,你需要创建一个定制的ArrayAdapter,它继承了Android的ArrayAdapter类,并重写了getView方法。添加一个新的java类到你的工程中,命名为WeatherAdapter,具体的实现代码如下:
1 WeatherAdapter.java文件:
2 public class WeatherAdapter extends ArrayAdapter<Weather>{
3
4 Context context;
5 int layoutResourceId;
6 Weather data[] = null;
7
8 public WeatherAdapter(Context context, int layoutResourceId, Weather[] data) {
9 super(context, layoutResourceId, data);
10 this.layoutResourceId = layoutResourceId;
11 this.context = context;
12 this.data = data;
13 }
14
15 @Override
16 public View getView(int position, View convertView, ViewGroup parent) {
17 View row = convertView;
18 WeatherHolder holder = null;
19
20 if(row == null)
21 {
22 LayoutInflater inflater = ((Activity)context).getLayoutInflater();
23 row = inflater.inflate(layoutResourceId, parent, false);
24
25 holder = new WeatherHolder();
26 holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon);
27 holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);
28
29 row.setTag(holder);
30 }
31 else
32 {
33 holder = (WeatherHolder)row.getTag();
34 }
35
36 Weather weather = data[position];
37 holder.txtTitle.setText(weather.title);
38 holder.imgIcon.setImageResource(weather.icon);
39
40 return row;
41 }
42
43 static class WeatherHolder
44 {
45 ImageView imgIcon;
46 TextView txtTitle;
47 }
48 }
在上面的代码中,第一个比较重要的是类的构造函数有三个参数,第一个参数是Context对象(我们可以传递当前使用WeatherAdapter类的activity对象的引用,即MainActivity.this对象);第二个参数是resource的id(它是我们想用来呈现每个ListView的item的布局文件的id),在本文中我将传递我创建的listview_item_row.xml布局文件的id;第三个参数是一个Weather对象的数组,用于为Adapter适配器提供显示数据的数据源。
ArrayAdapter的getView方法被重写了。这个方法将被ListView每个 item项调用来创建视图View,它们的属性是我们设置的。getView方法也使用了一个临时的holder类(在WeatherAdapter类内部声明的内部类),这个类将被用于缓存ImageView和TextView,以便它们能够被ListView中的每行重用,这也会为我们带来巨大的性能的提升,由于我们不断地访问两个相同的views(ImageView和TextView)的属性,我们不必为每个ListView的Item查找这两个控件。上面的代码也是用了Android内置的LayoutInflator来解析xml布局文件(用于动态加载xml布局文件,以便能够查找其中的内容)。
最后一点代码是我们应用的MainActivity。里面,我们使用了所有上面声明的对象。下面是MainActivity.java文件的代码:
MainActivity.java文件:
2 public class MainActivity extends Activity {
3
4 private ListView listView1;
5
6 @Override
7 public void onCreate(Bundle savedInstanceState) {
8 super.onCreate(savedInstanceState);
9 setContentView(R.layout.main);
10
11 Weather weather_data[] = new Weather[]
12 {
13 new Weather(R.drawable.weather_cloudy, "Cloudy"),
14 new Weather(R.drawable.weather_showers, "Showers"),
15 new Weather(R.drawable.weather_snow, "Snow"),
16 new Weather(R.drawable.weather_storm, "Storm"),
17 new Weather(R.drawable.weather_sunny, "Sunny")
18 };
19
20 WeatherAdapter adapter = new WeatherAdapter(this,
21 R.layout.listview_item_row, weather_data);
22
23
24 listView1 = (ListView)findViewById(R.id.listView1);
25
26 View header = (View)getLayoutInflater().inflate(R.layout.listview_header_row, null);
27 listView1.addHeaderView(header);
28
29 listView1.setAdapter(adapter);
30 }
MainActivity.java文件中有几个需要解释下的地方,以便你能更好的理解。首先,我们创建了一个Weather对象的数组,icon和title被作为参数传递给了它的构造函数;接下来,WeatherAdapter对象被创建,listview_item_row.xml文件的id和Weather对象数组被传递给了它的构造函数。再一次,我们使用了Android的LayoutInflator来解析listview_item_row.xml布局文件。通过ListView的addHeaderView方法设置ListView的header信息。最后,我们传递定制的Adapter给ListView的setAdapter方法。到现在就可以构建、运行工程了。如果一切实现正确,你会看到下面的内容。
图2. 运行效果
最近有一段时间没写东西了,真是罪过啊!翻译之中有不当之处在所难免,大家相互学习。尊重原创,尊重知识,相信分享的力量!
首先在一个控件加上这么一句:android:onClick=”doClick”//doClick为方法名,可以自定义
然后在Activity中写上一个doClick方法:
public void doClick(View view){
//多个控件用
switch(view.getId()){
case R.id.xx:
break;
…
}
就可以完成一个控件监听,对于一些不需要定义只需要监听的控件,或者很多需要监听的控件,这种方法多么好用呀~
缺点来了,
1、在Fragment里,就不能用了,在使用Dailog时,也不能用。
2、当你给控件加了这个属性却没在Activity写方法,那么你点击这个控件的时候,程序会崩溃,这也是个小缺陷,不友好。
但是,有些情况下,你还是很值得用这个的,省了很多时间。
Android倒计时功能开发例子比较简单了,在网上一搜索有好几个这种方法,我来给各位整理一下,具体如下所示。项目中经常会遇到找回密码的功能,现在找回密码一般都是用手机接收验证码,为了防止多次发送,一般需要设置一个发送间隔,比如60秒。为了让用户更加清楚的感受到这个间隔,于是就出现了倒计时功能.如下图:
点击之后,获取验证码的那个TextView或者Button变为不可点击,并且它的的text就要每秒变化一次,59,58,57…到最后一秒之后,text重新变为点击获取验证码,而且变为可点击.
看了一些前辈写的倒计时,都是用Handler和TimerTask来实现,然后我发现了一个更加简单的,Android自带的类来写这个功能.
接下来我就以一个简单的例子来实现这个功能。
1、activity_main.XML,为一个Button即可.
<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”
>
<Button
android:textSize=”25dp”
android:id=”@+id/btn_get”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:text=”点击获取验证码” />
</RelativeLayout>
2、MainActivity.java,既为重头戏,又极为简单.
package com.example.rr;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private Button mButton;//定义一个Button
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton=(Button) findViewById(R.id.btn_get);//←←获取按钮ID
//设置监听↓↓
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
mButton.setClickable(false);
mButton.setTextColor(Color.parseColor(“#FF0000″));
MyTimer myTimer=new MyTimer(5000, 1000);//定义MyTimer的对象
myTimer.start();//启动倒计时
}});
}
private class MyTimer extends CountDownTimer{
//millisInFuture为你设置的此次倒计时的总时长,比如60秒就设置为60000
//countDownInterval为你设置的时间间隔,比如一般为1秒,根据需要自定义。
public MyTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
// TODO Auto-generated constructor stub
}@Override
public void onTick(long millisUntilFinished) {
// TODO Auto-generated method stub
mButton.setText(millisUntilFinished/1000+”秒后重新获取”);
}
//每过你规定的时间间隔做的操作↑↑
//倒计时结束时做的操作↓↓
@Override
public void onFinish() {
// TODO Auto-generated method stub
mButton.setClickable(true);
mButton.setTextColor(Color.parseColor(“#000000”));
mButton.setText(“点击获取验证码”);
}}}
在各个关键点我也做了标注,下面是我给大家录的gif.
timer
大家可以发现有2个问题:
1、在1秒的时候,会停顿大约两秒,这样就给了用户不太好的体验,还以为是手机卡了.为什么会出现这种问题呢?
2、点击Button时,出现的是数字4而不是数字5。
首先我们得知道这种方法的原理是什么,大家先看一下CountDownTimer的源码:
首先大家看一下这句: mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;
再看下下面的这句: final long millisLeft = mStopTimeInFuture – SystemClock.elapsedRealtime();
(注意:SystemClock.elapsedRealtime()返回的是系统运行到现在的时间,每时每刻都在变化);
如果简单的进行数学计算的话,那么一开始mStopTimeInFuture是等于millisLeft的,但是不然,SystemClock.elapsedRealtime()返回的时间,以毫秒为单位,也就是说,从上面运行到下面,也消耗了些许时间,那么millisLeft就是小于5000的。
回到我们的Activity,我们在内部类的OnTick里写了什么?
mButton.setText(millisUntilFinished/1000+”秒后重新获取”);那么4900多除以1000后,返回的数值为4。
解决方案:
在我们实例化MyTimer时,将5000改为6000.
至于在1秒处停顿的情况,我们看一下最下面的if else 语句:
if (millisLeft <= 0) {
onFinish();
} else if (millisLeft < mCountdownInterval) {
// no tick, just delay until done
sendMessageDelayed(obtainMessage(MSG), millisLeft);
} else {
long lastTickStart = SystemClock.elapsedRealtime();
onTick(millisLeft);
在 else if 语句处,当millisLeft<mCountdownInterval=1000,时,只进行停顿,而不调用OnTick方法,也就是说,我们运行程序时,millisLeft的数值从4900多~3900~2900~1900~900,900的时候,运行到这里,就会停顿,而不显示我们在OnTick写的代码.
解决方案:
重写CountDownTimer类。
然后,
1、在else if 中加OnTick(millisLeft);
2、删掉这个if else 语句
OK,我在重写类之后,将if else 语句改为下面的时候,依旧可以完成倒计时功能:
if (millisLeft <= 0) {
onFinish();
} else {
onTick(millisLeft);
sendMessageDelayed(obtainMessage(MSG), 1000);
}
效果gif如下:
是不是写这个类的大牛想复杂了,还是我这个方法有问题呢?有知道的道友可以联系我~万分感谢!
PS:写这个文章浪费了快一下午,原因是网速不好,快写完了,保存草稿,然后出现意外,导致没保存,所以,,,,但是还是希望得到各位的建议和鼓励,谢谢!
EditText可以实现当用户输入内容时自动变成金额输入框了,今天我们就一起来看一个安卓开发的EditText一秒变身金额输入框例子。最近做的一个项目需要用到充值和提现金额,那么就需要在输入框中实现带小数点的金额数字,同时保证小数点后两位,于是在网上查了一些资料,实现了这样的功能。
首先,我们需要在布局中EditText中的属性里加上这样一句话:android:inputType=“numberDecimal”,表示输入的时候只能输入浮点型的数据。
自定义一个类,在这里写功能。
代码如下 | 复制代码 |
import android.text.InputFilter; import android.text.Spanned; import java.util.regex.Pattern; /** * joy on 2015/12/17. * * 金额输入格式 */ public class EditInputFilter implements InputFilter { /** * 最大数字,我们取int型最大值 */ public static final int MAX_VALUE = 2147483647; /** * 小数点后的数字的位数 */ public static final int PONTINT_LENGTH = 2; Pattern p; public EditInputFilter(){ p = Pattern.compile(“[0-9]*”); //除数字外的其他的 } /** * source 新输入的字符串 * start 新输入的字符串起始下标,一般为0 * end 新输入的字符串终点下标,一般为source长度-1 * dest 输入之前文本框内容 * dstart 原内容起始坐标,一般为0 * dend 原内容终点坐标,一般为dest长度-1 */ @Override public CharSequence filter(CharSequence src, int start, int end, Spanned dest, int dstart, int dend) { String oldtext = dest.toString(); System.out.println(oldtext); //验证删除等按键 if (“”.equals(src.toString())) { return null; } //验证非数字或者小数点的情况 Matcher m = p.matcher(src); if(oldtext.contains(“.”)){ //已经存在小数点的情况下,只能输入数字 if(!m.matches()){ return null; } }else{ //未输入小数点的情况下,可以输入小数点和数字 if(!m.matches() && !src.equals(“.”) ){ return null; } } //验证输入金额的大小 if(!src.toString().equals(“”)){ double dold = Double.parseDouble(oldtext+src.toString()); if(dold > MAX_VALUE){ return dest.subSequence(dstart, dend); }else if(dold == MAX_VALUE){ if(src.toString().equals(“.”)){ return dest.subSequence(dstart, dend); } } } //验证小数位精度是否正确 if(oldtext.contains(“.”)){ int index = oldtext.indexOf(“.”); int len = dend – index; //小数位只能2位 if(len > PONTINT_LENGTH){ CharSequence newText = dest.subSequence(dstart, dend); return newText; } } return dest.subSequence(dstart, dend) +src.toString(); } } 如何使用我们自定义的类呢,只需要在相应的Activity中定义EditText 控件edit_takeout_money;,然后: InputFilter[] filters = { new EditInputFilter() }; edit_takeout_money.setFilters(filters); 就OK了 |
这里贴上一个Demo的源码,分享一下:
代码如下 | 复制代码 |
import java.text.SimpleDateFormat; private TextView tvTime, tvOptions; @Override @Override @Override } public static String getTime(Date date) {
|
当然只有上面一个源码文件肯定是不行的,分享这两个Demo的项目地址,大家可以去看一下。
http://itlanbao.com/code/users/10000/20150911/Android-PickerView-master.rar
例子2
代码如下 | 复制代码 |
自定义一个类: package com.wwj.datetimepicker; import java.text.SimpleDateFormat; import android.app.Activity; /** /** } public void init(DatePicker datePicker, TimePicker timePicker) { datePicker.init(calendar.get(Calendar.YEAR), /** ad = new AlertDialog.Builder(activity) onDateChanged(null, 0, 0, 0); public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { public void onDateChanged(DatePicker view, int year, int monthOfYear, calendar.set(datePicker.getYear(), datePicker.getMonth(), dateTime = sdf.format(calendar.getTime()); /** // 将初始日期时间2012年07月02日 16:45 拆分成年 月 日 时 分 秒 String yearStr = spliteString(date, "年", "index", "front"); // 年份 String monthStr = spliteString(monthAndDay, "月", "index", "front"); // 月 String hourStr = spliteString(time, ":", "index", "front"); // 时 int currentYear = Integer.valueOf(yearStr.trim()).intValue(); calendar.set(currentYear, currentMonth, currentDay, currentHour, /** }
package com.wwj.datetimepicker; import android.app.Activity; /** private String initStartDateTime = "2013年9月3日 14:44"; // 初始化开始时间 @Override // 两个输入框 startDateTime.setText(initStartDateTime); startDateTime.setOnClickListener(new OnClickListener() { DateTimePickDialogUtil dateTimePicKDialog = new DateTimePickDialogUtil( } endDateTime.setOnClickListener(new OnClickListener() { public void onClick(View v) { 自定义界面: <?xml version="1.0" encoding="utf-8"?> <DatePicker <TimePicker </LinearLayout> |
相关文章
- “一起,让我们将这个世界变得更好。”苹果首席执行官蒂姆 库克对着台下5000多名开发者说道,声音略有些沙哑和颤抖。...2016-07-04
- 有时为了网站安全和版权问题,会对自己写的php源码进行加密,在php加密技术上最常用的是zend公司的zend guard 加密软件,现在我们来图文讲解一下。 下面就简单说说如何...2016-11-25
- ps软件是现在很多人都会使用到的,HSL面板在ps软件中又有着非常独特的作用。这次文章就给大家介绍下ps怎么使用HSL面板,还不知道使用方法的下面一起来看看。  ...2017-07-06
- 许多的朋友对于Plesk控制面板应用不是非常的了解特别是英文版的Plesk控制面板,在这里小编整理了一些关于Plesk控制面板常用的使用方案整理,具体如下。 本文基于Linu...2016-10-10
使用insertAfter()方法在现有元素后添加一个新元素
复制代码 代码如下: //在现有元素后添加一个新元素 function insertAfter(newElement, targetElement){ var parent = targetElement.parentNode; if (parent.lastChild == targetElement){ parent.appendChild(newEl...2014-05-31- 大概有如下步骤 新建项目Bejs 新建文件package.json 新建文件Gruntfile.js 命令行执行grunt任务 一、新建项目Bejs源码放在src下,该目录有两个js文件,selector.js和ajax.js。编译后代码放在dest,这个grunt会...2014-06-07
使用percona-toolkit操作MySQL的实用命令小结
1.pt-archiver 功能介绍: 将mysql数据库中表的记录归档到另外一个表或者文件 用法介绍: pt-archiver [OPTION...] --source DSN --where WHERE 这个工具只是归档旧的数据,不会对线上数据的OLTP查询造成太大影响,你可以将...2015-11-24如何使用php脚本给html中引用的js和css路径打上版本号
在搜索引擎中搜索关键字.htaccess 缓存,你可以搜索到很多关于设置网站文件缓存的教程,通过设置可以将css、js等不太经常更新的文件缓存在浏览器端,这样访客每次访问你的网站的时候,浏览器就可以从浏览器的缓存中获取css、...2015-11-24jQuery 1.9使用$.support替代$.browser的使用方法
jQuery 从 1.9 版开始,移除了 $.browser 和 $.browser.version , 取而代之的是 $.support 。 在更新的 2.0 版本中,将不再支持 IE 6/7/8。 以后,如果用户需要支持 IE 6/7/8,只能使用 jQuery 1.9。 如果要全面支持 IE,并混合...2014-05-31安装和使用percona-toolkit来辅助操作MySQL的基本教程
一、percona-toolkit简介 percona-toolkit是一组高级命令行工具的集合,用来执行各种通过手工执行非常复杂和麻烦的mysql和系统任务,这些任务包括: 检查master和slave数据的一致性 有效地对记录进行归档 查找重复的索...2015-11-24- C#注释的一些使用方法浅谈,需要的朋友可以参考一下...2020-06-25
- 一、下载 mysqlsla [root@localhost tmp]# wget http://hackmysql.com/scripts/mysqlsla-2.03.tar.gz--19:45:45-- http://hackmysql.com/scripts/mysqlsla-2.03.tar.gzResolving hackmysql.com... 64.13.232.157Conn...2015-11-24
- 目前,JSON已经成为最流行的数据交换格式之一,各大网站的API几乎都支持它。我写过一篇《数据类型和JSON格式》,探讨它的设计思想。今天,我想总结一下PHP语言对它的支持,这是开发互联网应用程序(特别是编写API)必须了解的知识...2015-10-30
- 无限级分类在开发中经常使用,例如:部门结构、文章分类。无限级分类的难点在于“输出”和“查询”,例如 将文章分类输出为<ul>列表形式; 查找分类A下面所有分类包含的文章。1.实现原理 几种常见的实现方法,各有利弊。其中...2015-10-23
- 设置登录密码我们一般会有限制的如由什么组合了,下面我们来看一篇关于安卓开发之设置密码只能输入字母和数字的组合方法,具体的细节如下所示。 无论是电脑还是手机...2016-09-20
- php类的使用实例教程 <?php /** * Class program for yinghua05-2 * designer :songsong */ class Template { var $tpl_vars; var $tpl_path; var $_deb...2016-11-25
- 前几天在百度知道里面看到有人问PHP中双冒号::的用法,当时给他的回答比较简洁因为手机打字不大方便!今天突然想起来,所以在这里总结一下我遇到的双冒号::在PHP中使用的情况!双冒号操作符即作用域限定操作符Scope Resoluti...2015-11-08
- mysqli封装了诸如事务等一些高级操作,同时封装了DB操作过程中的很多可用的方法。应用比较多的地方是 mysqli的事务。...2013-10-02
Postman安装与使用详细教程 附postman离线安装包
这篇文章主要介绍了Postman安装与使用详细教程 附postman离线安装包,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-05- Promise是异步编程的一种解决方案,在ES6中Promise被列为了正式规范,统一了用法,原生提供了Promise对象。接下来通过本文给大家介绍Promise的介绍及基本用法,感兴趣的朋友一起看看吧...2021-10-21