( 环境AS3.0,安卓8.0)
还有别的方法,比如在getWindow() 下边设置 requestWindowFeature(Window.FEATURE_NO_TITLE) ,但不管用。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//隐藏标题栏以及状态栏,必须写在setContentView之前
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_welcome);
handler.sendEmptyMessageDelayed(0,2000);
}
AndroidManifest.xml 清单文件是每个 Android 项目所必须的,它是整个 Android 应用的全局描述文件。清单文件说明了该应用的名称、所使用的图标以及包含的组件等。
通常包含以下信息:
1.应用程序的包名,该包名将会作为该应用的唯一标识。
2.应用所包含的组件,如Activity、Service、BroadcastRwceiver和ContentProvider等。
3.应用兼容的最低版本。
4.应用程序使用系统所需的权限声明。
5.其他程序访问该程序所需的权限声明。
当一个Activity启动另一个Activity时,常常会有一些数据需要传递过去——就像Web应用从一个Servlet跳到另一个Servlet时,习惯把需要交换的数据放入requestScope、sessionScope中。对于Activity而言,在Activity之间进行数据交换更简单,因为两个Activity之间本来就有一个“信使”:Intent,因此我们主要将需要交换的数据放入Intent中即可。
Intent提供了多个重载的方法来“携带”额外的数据,如下所示。
1.putExtras(Bundle data):向Intent中放入需要“携带”的数据包。
2.Bundle getExtras():取出数据包。
3.putExtra(String name,Xxx value):向Intent中按Key-Value对的形式存入数据。
4.getXxxExtra(String name):从Intent中按Key取出指定类型的数据。
Bundle包含多个方法存\取数据。
1.putXxx(String name,Xxx data):向Bundle中放入Int、Long等各种类型的数据。
2.putSerializable(String Key, Serializable data):向Bundle中放入一个可序列化的对象。
3.getXxx(String name):从Bundle中取出Int、Long等各种类型的数据。
4.getSerializable(String name, Serializable data):从Bundle中取出一个序列化对象。
注意:
Intent的putExtra(Sting name, Xxx Value)方法是“智能”的,当程序调用Intent的putExtra(String name, Xxx Value)方法向Intent存数据时,如果该Intent中已经携带了Bundle对象,则该方法直接向Intent所携带的Bundle中存入数据;如果没有携带Bundle对象,则putExtra(String name, Xxx Value)方法先创建一个Bundle,再向Bundle中存入数据。
// 第一个Activity
Person p = new Person();
Bundle data = new Bundle();
data.putSerializable("person",p);
Intent intent = new Intent(thisActivity.this,targetActivity.class);
intent.putxtras(data);
startActivity(intent);
// 第二个Activity
Intent intent = getIntent();
Person p = (Person)intent.getSerializable("person");
想要实现这一功能。需要在主清单文件中通过设置android:parentActivityName 属性,去声明你当前交互界面的上一级交互界面。
例子:
只用在配置文件设置即可。
版权声明:本文为 stormzhang 原创文章,可以随意转载,但必须在明确位置注明出处!!!转自:http://stormzhang.com/android/2015/03/29/android-support-library/
来自于知乎上邀请回答的一个问题Android中AppCompat和Holo的一个问题?, 看来很多人还是对这些兼容包搞不清楚,那么干脆写篇博客吧.
我们都知道Android一些SDK比较分裂,为此google官方提供了Android Support Library package 系列的包来保证高版本sdk开发的向下兼容性, 所以你可能经常看到v4,v7,v13这些数字,首先我们就来理清楚这些数字的含义,以及它们之间的区别。
用在API lever 4(即Android 1.6)或者更高版本之上。它包含了相对更多的内容,而且用的更为广泛,例如:Fragment,NotificationCompat,LoadBroadcastManager,ViewPager,PageTabStrip,Loader,FileProvider 等
Gradle引用方法:
compile 'com.android.support:support-v4:21. 0.3'
这个包是为了考虑API level 7(即Android 2.1)及以上版本而设计的,但是v7是要依赖v4这个包的,v7支持了Action Bar以及一些Theme的兼容。
Gradle引用方法:
compile 'com.android.support:appcompat-v7:21.0.3'
这个包的设计是为了API level 13(即Android 3.2)及更高版本的,一般我们都不常用,平板开发中能用到,这里就不过多介绍了。
回到知乎上的这个问题,我们来介绍下各种Theme的概念。
在4.0之前Android可以说是没有设计可言的,在4.0之后推出了Android Design,从此Android在设计上有了很大的改善,而在程序实现上相应的就是Holo风格,所以你看到有类似 Theme.Holo.Light、 Theme.Holo.Light.DarkActionBar 就是4.0的设计风格,但是为了让4.0之前的版本也能有这种风格怎么办呢?这个时候就不得不引用v7包了,所以对应的就有 Theme.AppCompat.Light、 Theme.AppCompat.Light.DarkActionBar,如果你的程序最小支持的版本是4.0,那么可以不用考虑v7的兼容。
今年的5.0版本,Android推出了Material Design的概念,这是在设计上Android的又一大突破。对应的程序实现上就有 Theme.Material.Light、 Theme.Material.Light.DarkActionBar等,但是这种风格只能应用在在5.0版本的手机,如果在5.0之前应用Material Design该怎么办呢?同样的引用appcompat-v7包,这个时候的Theme.AppCompat.Light、 Theme.AppCompat.Light.DarkActionBar就是相对应兼容的Material Design的Theme。
gradle引用appcompat-v7包的时候就不需要引用v4了,因为v7里默认包含了v4包;
compile ‘com.android.support:appcompat-v7:21.0.3’ 中的21代表API level 21推出的兼容包,所以如果你引用的是21之前的版本,则默认这些Theme.AppCompat.Light是Holo风格的,从21开始的版本默认是Material风格
使用appcompat之后,你的所有的Activity应该继承自ActionBarActivity,而ActionBarActivity继承自FragmentActivity,所以放心的使用Fragment;
如果英语好的,可直接移步官方最权威的解释https://developer.android.com/tools/support-library/features.html
补充:
Activity 发展到3.0(大概)之后,可以使用fragment了,但是support v4 提供了1.6~3.0的fragment兼容,所以如果需要用兼容版的fragment,则需要继承support v4提供的FragmentActivity。而后一点点时间之后,3.0(大概)出现的ActionBar也被向前支持了,这次是出现在support v7里,如果需要使用兼容版的actionbar,则继承support v7提供的ActionBarActivity(它是继承FragmentActivity的)。再然后也就是去年年底到今年,5.0提供了很多很多新东西,于是support v7也更新了,出现了AppCompatActivity , 具体功能请自行查找。
简介:用于直接把git上的android studio项目直接运行在启动的虚拟机上,省去下载包、同步gradle、调试步骤——干运行。简单、暴力。
安装ruby-devkit包,不用分开安装,省事。
控制台gem install dryrun
如果报错如下:
invalid gem: package is corrupt, exception while verifying: undefined method `size’ for nil:NilClass (NoMethodError)
解决方法:
# gem env
得到gem的PATH路径,比如
- GEM PATHS:
- /usr/local/ruby/lib/ruby/gems/2.1.0
- /home/vagrant/.gem/ruby/2.1.0
将其下的cache目录删除,再次执行gem安装的时候就不会出错了
不过最后一步报错,不知道为什么。
在安卓系统中,只允许UI线程修改Activity里面的组件。
当程序第一次启动时,Android会同时启动一条主线程(Main Thread),主线程主要负责处理与UI相关的事件,如用户的按键事件、用户接触屏幕的事件及屏幕绘图事件,并把相关的事件分发到对应的组件进行处理。所以,主线程同城又称为UI线程。
Android的消息传递机制是另一种形式的“事件处理”,这种机制主要是为了解决Android应用的多线程问题——Android平台只允许UI线程修改Activity里的UI组件,这样就会导致新启动的线程无法动态改变界面组件的属性值。但在实际的开发中,尤其是动画的游戏开发中,需要让新启动的线程周期性的改变界面组件的属性值,这就需要借助于Handler的消息传递机制来实现了。
handler类的作用主要有两个:
上面的说法看似很简单,只要分两步即可:在新启动的线程中发送消息;然后再主线程中去获取并处理消息。但这个过程涉及两个问题:新启动的线程何时发送消息呢?主线程何时去获取处理消息呢?这个时机显然不好控制。
为了让主线程能“适时”的处理新启动的线程所发送的消息,显然只能通过回调的方式来实现——开发者只要重写Handler类中处理消息的方法,当新启动的线程发送消息时,消息会发送到与之相联的MessageQueue,而Handler会不断的从MessageQueue中获取并处理消息——这将会导致Handler类中处理消息的方法被回调。
Handler类包含如下方法用于发送、处理消息。
自动播放图片示例代码:
public class MainActivity extends Activity
{
// 定义周期性显示的图片的ID
int[] imageIds = new int[]
{
R.drawable.java,
R.drawable.javaee,
R.drawable.ajax,
R.drawable.android,
R.drawable.swift
};
int currentImageId = 0;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final ImageView show = (ImageView) findViewById(R.id.show);
final Handler myHandler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
// 如果该消息是本程序所发送的
if (msg.what == 0x1233)
{
// 动态地修改所显示的图片
show.setImageResource(imageIds[currentImageId++
% imageIds.length]);
}
}
};
// 定义一个计时器,让该计时器周期性地执行指定任务
new Timer().schedule(new TimerTask()
{
@Override
public void run()
{
// 发送空消息
myHandler.sendEmptyMessage(0x1233);
}
}, 0, 1200);
}
}
下面介绍一下雨handler一起工作的几个组件。
将下句粘贴到xml头部。
xmlns:app="http://schemas.android.com/apk/res-auto"
分为以下几个步骤:
背景:如微信,主界面是由四个fragment组成,随意点击其中一个fragment里的组件就能跳转到activity,之后还能返回到入口fragment。
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(getActivity(),SetActivity.class);
intent.putExtra("tabFlag",2);
startActivity(intent);
}
});
@Override
protected void onResume() {
int id = getIntent().getIntExtra("tabFlag",0);
if(id==2){
//设置为当前页面
viewPagerIndicator.setViewPager(viewPager,2);
}
super.onResume();
}
前提:一个Activity有很多事件,只是其中一个事件跳转后不能返回,其他还可以。就比如:设置里面一般有退出账号,点击退出之后就不能再反回之前activity了。
在startActivity(intent)之后,添加finish();
缺陷:是不能返回入口Activity,但会返回到入口Activity的上一层Activity。
添加返回事件
private long exitTime = 0;
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_BACK && event.getAction()==KeyEvent.ACTION_DOWN){
if(System.currentTimeMillis()-exitTime>2000){
Toast.makeText(getApplicationContext(),"再按一次退出程序",Toast.LENGTH_SHORT).show();
exitTime = System.currentTimeMillis();
}else{
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
}
return true;
}
return super.onKeyDown(keyCode, event);
}
有区别。Actionbar的返回是返回上一个目录,手机返回是返回上一个页面。所以在微信中浏览公众号内容时,如果有多个连接,那手机返回按键会一个一个返回,而左上角返回就直接跳到上一目录。
private String[] names = new String[]{
"周俊","刘帅","亮亮","坤","吕江","先进","翎姐","康哥","李瑞","老田"
};
private ListView listView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_friends, container,false);
listView = view.findViewById(R.id.friendList);
ArrayAdapter adapter = new ArrayAdapter(getActivity(),android.R.layout.simple_list_item_1, names);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
Toast.makeText(view.getContext(),names[position]+"被点击",Toast.LENGTH_SHORT).show();
}
});
return view;
}
自定义列表
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_chatlist,container,false);
listView = view.findViewById(R.id.chatList);
List
虚拟器应访问ip为10.0.2.2:8080/
可以开启虚拟器,打开浏览器输入地址进行访问。
原因是默认没有访问网络所需的权限。
如果需要访问网络需要在AndroidManifest.xml中,进行如下配置:
简介
当我们平常运行AS编译器,发生如下错误
Error:Execution failed for task ‘:app:preDebugAndroidTestBuild’.
Conflict with dependency ‘com.android.support:support-annotations’ in project ‘:app’. Resolved versions for app (22.1.0) and test app (25.4.0) differ. See https://d.android.com/r/tools/test-apk-dependency-conflicts.html for details.
发生这类型的错误,是当我们修改了.build中的compileSdkVersion,产生所依赖的dependency与当前版本不一致导致的。
解决
build->Rebuid-project
定义一个 final 类型的 int 变量和硬编码一个值的方式都是行不通的。
错误提示:
java.lang.IllegalArgumentException: The key must be an application-specific resource id.
既然要求是资源Id,那就定义个ID不就行了
如下:
有效解决问题
viewHolder.agree.setTag(R.id.tag_0,position);
viewHolder.agree.setTag(R.id.tag_1,viewHolder.agree);
viewHolder.agree.setTag(R.id.tag_2,viewHolder.refuse);
viewHolder.agree.setTag(R.id.tag_3,"1");
Tag中可以传递对象,对象可以是View,那就很强大了。
比如有这么个需求:
ListView中有两个按钮,同意或拒绝,点击任何一个后两个按钮都设置成不可点击,并且点击的按钮设置成绿色。
因为OnClick方法只能传递一个参数View,就是只能传递一个控件。要传递其他信息,就要把信息封装在View中,就是setTag()。
public void click(View v) {
Button agree = (Button) v.getTag(R.id.tag_1);
Button refuse = (Button)v.getTag(R.id.tag_2);
String flag = (String )v.getTag(R.id.tag_3);
Integer pos = (Integer) v.getTag(R.id.tag_0);
if(flag.equals("0")){
refuse.setBackgroundColor(getResources().getColor(R.color.colorGreen));
Toast.makeText(getApplicationContext(),pos+"拒绝",Toast.LENGTH_SHORT).show();
}else{
agree.setBackgroundColor(getResources().getColor(R.color.colorGreen));
Toast.makeText(getApplicationContext(),pos+"同意",Toast.LENGTH_SHORT).show();
}
agree.setClickable(false);
refuse.setClickable(false);
}
设置回调函数
public class AddFriendAdapter extends ArrayAdapter implements View.OnClickListener{
private int resourseId;
private Callback mCallback;
public interface Callback {
public void click(View v);
}
public AddFriendAdapter(@NonNull Context context, int resource, @NonNull List objects,Callback callback) {
super(context, resource, objects);
this.resourseId = resource;
mCallback = callback;
Log.d("MsgAdapter","resourseId:"+resourseId);
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
AddFriend addFriendMsg = getItem(position);
View view ;
AddFriendAdapter.ViewHolder1 viewHolder;
if(convertView == null){
view = LayoutInflater.from(getContext()).inflate(resourseId,null);
viewHolder = new AddFriendAdapter.ViewHolder1();
viewHolder.toLayout = view.findViewById(R.id.apply_to_me);
viewHolder.fromLayout = view.findViewById(R.id.apply_from_me);
viewHolder.agree = view.findViewById(R.id.button_apply_agree);
viewHolder.refuse = view.findViewById(R.id.button_apply_refuse);
viewHolder.toMsg = view.findViewById(R.id.text_to_info);
viewHolder.fromMsg = view.findViewById(R.id.text_from_info);
view.setTag(viewHolder);
}else{
view = convertView;
viewHolder = (AddFriendAdapter.ViewHolder1) view.getTag();
}
viewHolder.refuse.setOnClickListener(this);
viewHolder.agree.setOnClickListener(this);
viewHolder.agree.setTag(R.id.tag_0,position);
viewHolder.agree.setTag(R.id.tag_1,viewHolder.agree);
viewHolder.agree.setTag(R.id.tag_2,viewHolder.refuse);
viewHolder.agree.setTag(R.id.tag_3,"1");
viewHolder.refuse.setTag(R.id.tag_0,position);
viewHolder.refuse.setTag(R.id.tag_1,viewHolder.agree);
viewHolder.refuse.setTag(R.id.tag_2,viewHolder.refuse);
viewHolder.refuse.setTag(R.id.tag_3,"0");
if(addFriendMsg.getHostId() != ObjectManager.login.getId()){
viewHolder.toLayout.setVisibility(View.VISIBLE);
viewHolder.fromLayout.setVisibility(View.GONE);
viewHolder.toMsg.setText(addFriendMsg.getAddInfo());
}else{
viewHolder.toLayout.setVisibility(View.GONE);
viewHolder.fromLayout.setVisibility(View.VISIBLE);
viewHolder.fromMsg.setText(addFriendMsg.getAddInfo());
}
return view;
}
class ViewHolder1{
LinearLayout toLayout;
LinearLayout fromLayout;
Button agree;
Button refuse;
TextView toMsg;
TextView fromMsg;
}
@Override
public void onClick(View v) {
mCallback.click(v);
}
}
public class MsgFriendActivity extends AppCompatActivity implements AddFriendAdapter.Callback{
private ListView listView;
private AddFriendAdapter addFriendAdapter;
private Button refuse;
private Button agree;
private Gson gson;
private List msgList = new ArrayList();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_msgfriend);
listView = findViewById(R.id.list_msg_friend);
initData();
addFriendAdapter = new AddFriendAdapter(MsgFriendActivity.this,R.layout.item_infofriend,msgList,this);
listView.setAdapter(addFriendAdapter);
}
private void initData(){
gson = new Gson();
for(int i = 1; i < 6; i ++){
AddFriend addFriend = new AddFriend();
addFriend.setAddId(i+7);
addFriend.setAddInfo("小黄人+"+i);
addFriend.setApplyTime(new Date().toString());
addFriend.setHostId(5);
addFriend.setStatu('0');
msgList.add(addFriend);
}
for(int i = 1; i < 6; i ++){
AddFriend addFriend = new AddFriend();
addFriend.setAddId(i+7);
addFriend.setAddInfo("格鲁+"+i);
addFriend.setApplyTime(new Date().toString());
addFriend.setHostId(ObjectManager.login.getId());
addFriend.setStatu('0');
msgList.add(addFriend);
}
//msgList.addAll(ObjectManager.addMeList);
//msgList.addAll(ObjectManager.addFriendList);
}
@Override
public void click(View v) {
Button agree = (Button) v.getTag(R.id.tag_1);
Button refuse = (Button)v.getTag(R.id.tag_2);
String flag = (String )v.getTag(R.id.tag_3);
Integer pos = (Integer) v.getTag(R.id.tag_0);
if(flag.equals("0")){
refuse.setBackgroundColor(getResources().getColor(R.color.colorGreen));
Toast.makeText(getApplicationContext(),pos+"拒绝",Toast.LENGTH_SHORT).show();
}else{
agree.setBackgroundColor(getResources().getColor(R.color.colorGreen));
Toast.makeText(getApplicationContext(),pos+"同意",Toast.LENGTH_SHORT).show();
}
agree.setClickable(false);
refuse.setClickable(false);
}
}
c:\用户目录\.android\avd
定期删除,很占用存储空间