首页 > 代码库 > 刚学Android遇到的问题,findViewById值为null(新版本),老鸟欢迎你的指正
刚学Android遇到的问题,findViewById值为null(新版本),老鸟欢迎你的指正
环境交代:
刚学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了。