刚学
Android,在官网下载的新版的ADT
以及新版的SDK
在新版的IDE(ADT)创建项目时如果你的最小版本(minimum required SDK)要支持4.0以下版,并且目标版本为(4.0+).那么此时IDE会为你创建一个兼容包 (appcompat_v7)如下图,
创建发短信项目后就会有如下的项目目录结构
这个时候在生成的项目主Activity不是以前的那种继承的Activity,而是继承的ActionBarActivity,我把发短信的界面创建起。界面效果如下。点此时我用 this.findViewById(R.id.but_send);来得到发短信界面的Button按钮。但是没得到我想要的button,输出button为null。
这让我一个初学android的这咋整??百度一哈没有可用的答案,于是自己解决。
解决办法
捣鼓很久后捣鼓成功代码如下,原因是因为在新的layout文件不是存放在默认的(res/layout/activity_main.xml)文件中,而是存放在(res/layout/fragment_main.xml)文件中。所以要在fragment_main.xml去早对应的ID才会找到,而新的IDE生成的代码中加载(fragment_main.xml)文件是在一个内部加载的,所以我们可以在内部类加载处来得到Button:
package com.shuqi.cms;
import android.support.v7.app.ActionBarActivity;
import android.support.v4.app.Fragment;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity{
private static EditText edt_num = null;
private static EditText edt_content = null;
private static Button button = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
View rootView = null;
public PlaceholderFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_main, container, false);
edt_num = (EditText) rootView.findViewById(R.id.edt_cms_num);
edt_content = (EditText) rootView.findViewById(R.id.edt_cms_content);
button = (Button) rootView.findViewById(R.id.but_send);
// System.out.println(button);
return rootView;
}
}
public void onClick(View arg0) {
if(edt_num.getText().toString().trim().equals("")||edt_content.getText().toString().trim().equals("")){
Context context = getApplicationContext();
CharSequence text = "电话号码或者短信内容不能为空!!";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}else{
System.out.println("发短信");
}
}
}
效果图如下:
其他解决findViewById的值为空的方法:
原文地址:http://blog.sina.com.cn/s/blog_5e58565701012q2d.html
错误:findViewById返回Null,报nullpointer错误
网上搜了下,拾人牙慧,总结原因,一般为3种:
1.在另一个view的元素应该用baseView.findViewById()来拿
findViewById()是要指定view的,如果在该view下找不到,自然报null。平时注意养成写view.findViewById()的习惯就不容易错了。
2.findViewById在setContentView(R.layout.main);之前.
即在setContentView调用之前,调用了findViewById去找main布局中的界面元素lv_contactbook,那么所得到的lv一定是null。正确的做法是将上面代码中加粗的哪一行,挪至setContentView方法调用之后即可。
3.clean一下工程,让ID重新生成
这种情况是调用LayoutInflater.inflate将布局xml规定的内容转化为相应的对象。比如有rowview.xml布局文件(比如在自定义Adapter的时候,用作ListView中的一行的内容的布局),假定在自定的Adapter的getView方法中有类似如下的代码:
View rowview = (View)inflater.inflate(R.layout.rowview, parent, false);
TextView tv_contact_id =(TextView)rowview.findViewById(R.id.tv_contact_id);
TextView tv_contactname =(TextView)rowview.findViewById(R.id.tv_contactname);
有时候居然也会发现rowview非空,但tv_contact_id和tv_contactname都是null!仔细看代码,怎么也看不出错误来。到底是什么原因造成的呢?答案是Eclipse造成的,要解决这个问题,需要这个项目clean一次(Project菜单 -> Clean子菜单),这样就OK了。