对于想了解android–无法访问AsyncTask中的“findViewById”的读者,本文将是一篇不可错过的文章,我们将详细介绍无法访问android/data,并且为您提供关于actvity.
对于想了解android – 无法访问AsyncTask中的“findViewById”的读者,本文将是一篇不可错过的文章,我们将详细介绍无法访问android/data,并且为您提供关于actvity.findViewById() 与 view.findViewById()、Android findViewById与findViewWithTag()、Android findViewById使用技巧、Android findViewById返回NULL的有价值信息。
本文目录一览:- android – 无法访问AsyncTask中的“findViewById”(无法访问android/data)
- actvity.findViewById() 与 view.findViewById()
- Android findViewById与findViewWithTag()
- Android findViewById使用技巧
- Android findViewById返回NULL
android – 无法访问AsyncTask中的“findViewById”(无法访问android/data)
我正在使用AsyncTask类从PHP文件下载数据.下载后,我想把这些数据放到不同的TextViews中,但我不能使用findViewById方法.
问题是,我是通过单独的类来完成的,而这一切都在一个片段中.
这是我的代码:
public class RecuperarComentarisFoto extends AsyncTask<String, String, String>{
private Context mContext;
[...]
public RecuperarComentarisFoto(Context context){
this.mContext=context;
}
@Override
protected void onPreExecute() {
[...]
}
@Override
protected String doInBackground(String... arg0) {
params.add(new BasicNameValuePair("pid", "1"));
JSONObject json = jsonParser.makeHttpRequest(url_get_comentaris, "GET", params);
JSONArray productObj;
//HERE I RETRIEVE DATA FROM JSON. ITS WORKING OK.
return null;
}
我遇到问题的地方:
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
this.pDialog.dismiss();
TextView comentariEditText = (TextView) findViewById(R.id.commentsMostrar);
}
我试过这个:
TextView comentariEditText = (TextView) mContext.findViewById(R.id.commentsMostrar);
但是也不行.
请注意,我从片段中调用此AsyncTask.如您所见,我必须将getActivity()检索的上下文传递给AsyncTask:
public class MyFragmentA extends Fragment {
Context cont;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_a, container, false);
cont=getActivity();
new RecuperarComentarisFoto(cont).execute();
return myFragmentView;
}
}
我该怎么办?
谢谢.
解决方法:
将您的膨胀视图传递给AsyncTask,如下所示:
public class RecuperarComentarisFoto extends AsyncTask<String, String, String>{
private Context mContext;
private View rootView;
[...]
public RecuperarComentarisFoto(Context context, View rootView){
this.mContext=context;
this.rootView=rootView;
}
@Override
protected void onPreExecute() {
[...]
}
@Override
protected String doInBackground(String... arg0) {
params.add(new BasicNameValuePair("pid", "1"));
JSONObject json = jsonParser.makeHttpRequest(url_get_comentaris, "GET", params);
JSONArray productObj;
//HERE I RETRIEVE DATA FROM JSON. ITS WORKING OK.
return null;
}
@Override
protected void onPostExecute(String result) {
//super.onPostExecute(result); <--GET RID OF THIS (it will screw up on 2.1 devices)
this.pDialog.dismiss();
// use rootview to findViewById
TextView comentariEditText = (TextView) rootView.findViewById(R.id.commentsMostrar);
}
然后这样打电话,
View myFragmentView = inflater.inflate(R.layout.fragment_a, container, false);
cont=getActivity();
new RecuperarComentarisFoto(cont, myFragmentView).execute();
actvity.findViewById() 与 view.findViewById()
自从学习android的hello world开始
我们就知道了这样一个函数findViewById(),他已经成为了家喻户晓,坑蒙拐骗,杀人越货必备的一个函数(好吧,这句是扯淡)
但一直用也没细致研究过它,直到写程序的时候发现一个由这个函数引起的一个莫名其妙的bug,遂决定好好研究下次函数~
我们调用的findViewById()函数其实有两种(目前我只看到两种,不确定还有没有其他的),一种是Activity类中findViewById()函数
另外一种是View类中定义的findViewById()函数
一般我们在oncreate()方法中使用的(**view)findViewById(R.id.**)既是调用的Activity中的findViewById()函数
而在其他情况写出的***view.findViewById()中调用的是view类中的findViewById()
分别看一下源代码中的实现方法及介绍
Activity类中定义的findViewById()
[java]
/**
* Finds a view that was identified by the id attribute from the XML that
* was processed in {@link #onCreate}.
*
* @return The view if found or null otherwise.
*/
public View findViewById(int id) {
return getWindow().findViewById(id);
}
/**
* Retrieve the current {@link android.view.Window} for the activity.
* This can be used to directly access parts of the Window API that
* are not available through Activity/Screen.
*
* @return Window The current window, or null if the activity is not
* visual.
*/
public Window getWindow() {
return mWindow;
}
从这里可以看出这个函数是在寻找在xml中定义的指定id的对象
View类中的findViewById()
[java]
/**
* Look for a child view with the given id. If this view has the given
* id, return this view.
*
* @param id The id to search for.
* @return The view that has the given id in the hierarchy or null
*/
public final View findViewById(int id) {
if (id < 0) {
return null;
}
return findViewTraversal(id);
/**
* {@hide}
* @param id the id of the view to be found
* @return the view of the specified id, null if cannot be found
*/
protected View findViewTraversal(int id) {
if (id == mID) {
return this;
}
return null;
}
从这里可以看出我们是从一个view的child view中寻找指定id的对象,所以即使几个layout的XML文件中的View的id号相同的话,只要他们没有相同的父节点,或有相同的父亲节点,但不在父节点及以上节点调用findViewById通过id来查找他们就是没有问题。(这句引用自这里http://www.2cto.com/kf/201204/127404.html)
使用这个函数的常见问题:
1.既然Activity中的findViewById()是从R.java中寻找东西,那么我们就要杜绝相同名字的控件
今天自己的bug就是因为这个产生的
说到控件的命名,今天还有一个小发现
仔细看下边两段代码代码
[xml]
< ?xml version="1.0" encoding="utf-8"?>
< LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/LinearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
< /LinearLayout>
[xml]
< ?xml version="1.0" encoding="utf-8"?>
< LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
< /LinearLayout>
一段里边Layout没有id这个参数,一段里边有id,虽然代码不同但在outline中显示出来都是
这样在第一种情况下R.id中可以找到LinearLayout这个控件,第二种是没有的哈,这些也是以后要注意的细节
2.在调用view中的findViewById()一定要想好父View是谁!即**view.findViewById()中的**view要找对,如果没有找对父View,返回基本都是null了
Android findViewById与findViewWithTag()
一、方法介绍
android 平台获取控件的方式,一般使用View.findViewById(int)但还有一个方findViewWithTag(Object key),indViewById(int resId)适合正向匹配查询,而findViewWithTag(Object key)适合反向查询。但2者中,后者功能比较弱,不能查询到所有的具有该tag的View。
在这里,着重讲解findViewWithTag
实际操作,往往是对固定的tabcard,或者TabWidget来说非常合适,另外有些时候,对于没必要设置ViewHolder的控件来说也非常合适。
在自定义tabWidget时,饿哦们可以将每个widget的tab设置成tag,然后读取的方式非常好,当然,这功能可有可无。
二、代码实现
1.布局文件R.layout.main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- 这个布局决定了标签在上面还是在下面显示 -->
<FrameLayout
android:id="@+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" />
<android.support.v4.app.FragmentTabHost
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"/>
</android.support.v4.app.FragmentTabHost>
</LinearLayout>
2.java代码
public class MainActivity extends FragmentActivity {
private FragmentTabHost mTabHost = null;;
private View indicator = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
// 添加tab名称和图标
indicator = getIndicatorView("我的联系人", R.layout.mycontact_indicator);
mTabHost.addTab(mTabHost.newTabSpec("myContact")
.setIndicator(indicator), FirstFragment.class, null);
indicator = getIndicatorView("陌生人", R.layout.strangercontact_indicator);
mTabHost.addTab(
mTabHost.newTabSpec("stranger").setIndicator(indicator),
secondFragment.class, null);
indicator = getIndicatorView("常联系人", R.layout.alwayscontact_indicator);
mTabHost.addTab(
mTabHost.newTabSpec("alwaysContact").setIndicator(indicator),
ThirdFragment.class, null);
}
private View getIndicatorView(String name, int layoutId)
{
View v = getLayoutInflater().inflate(layoutId, null);
TextView tv = (TextView) v.findViewById(R.id.tabText);
tv.setText(name);
v.setTag(name); //设置tag
return v;
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
mTabHost = null;
}
}
alwayscontact_indicator.xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center">
<TextView
android:id="@+id/tabText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true"
android:drawableTop="@drawable/mycontact_selector"
android:textColor="@drawable/tabitem_txt_sel"/>
</LinearLayout>
3.当我们需要命令模式(是一种设计模式,类似于BroadcastReciever的Action进行Tab切换)先来建立一个内部类
private BroadcastReceiver commandBroadcast = new BroadcastReceiver()
{
private final String commondKey = "COMMOND_KEY";
@override
public void OnReceiver(Context cxt,Intent data)
{
if("我的联系人".equals(intent.getStringExtra(commondKey)))
{
mTabHost.setCurrentTag("myContact");
View layouView = mTabHost.getTabWidget().findViewWithTag("我的联系人");
}
else if("陌生人".equals(intent.getStringExtra(commondKey)))
{
mTabHost.setCurrentTag("stranger");
View layouView = mTabHost.getTabWidget().findViewWithTag("陌生人");
}
}
}
4.在Activity中注册commandBroadcast,Action使用(具体步骤略过)
cn.test.my.tab.action
5.当我们需要切换时tabcard时,直接可以发送广播
Intent intent = new Intent("cn.test.my.tab.action");
intent.putString("COMMOND_KEY","我的联系人");
sendBroadcast(intent);
就到这里,如有疑问,请留言
try doing it!
Android findViewById使用技巧
程序中初始化控件方法:(View)findViewById(int redID),而且还得强制转化为相应类型,code浪费大量的时间, 阅读起来也不美观。 //一般写法,很累跟强制转换似的,很难受这样写 tv_title_other = (TextView) findViewById(R.id.tv_title_other); //替代方式 protected <T extends View> T findView(int viewId) { return (T) findViewById(viewId); } //简化之后 tv_title_other = findView(R.id.tv_title_other);
代码片段
ViewGroup.java {
public ViewGroup(Context context, AttributeSet attrs) {
super((Context)null, (AttributeSet)null, 0, 0);
throw new RuntimeException("Stub!");
}
}
View.java {
public View(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
throw new RuntimeException("Stub!");
}
}
Android findViewById返回NULL
有时我的xml视图有一个奇怪的问题,并且包含在Android Eclipse SDK中的子元素.
例如,我有一个名为main.xml的xml视图,其中的LinearLayout和TextView是唯一的子级,其ID为textView1.一切正常(长时间).当进行一些主要的代码更改时,可能会发生findViewById(R.id.textView1);开始返回null.重新编译不会改变任何东西.真奇怪
一段时间后,我找到了一种解决方法…我将main.xml复制到main2.xml,并将setContentView(R.layout.main)更改为setContentView(R.layout.main2),并且一切正常,g继续进行,没有任何改变布局参考,甚至仅复制布局本身.没有内容被修改.在第一次运行之后,我可以删除main2.xml并将布局设置回R.layout.main.没有更多的NullPointerException.
有人知道发生了什么问题以及如何在不执行愚蠢的复制操作的情况下解决此问题吗?
最好,
哈克牛排
解决方法:
如果Eclipse有问题(例如强制关闭),这恰好发生在我身上.它对我有用的是清理项目,直到获得所有资源和引用为止.
今天关于android – 无法访问AsyncTask中的“findViewById”和无法访问android/data的介绍到此结束,谢谢您的阅读,有关actvity.findViewById() 与 view.findViewById()、Android findViewById与findViewWithTag()、Android findViewById使用技巧、Android findViewById返回NULL等更多相关知识的信息可以在本站进行查询。
本文标签: