android twitter リストビューにてActivityThreadで例外が発生する

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
LL

android twitter リストビューにてActivityThreadで例外が発生する

#1

投稿記事 by LL » 10年前

こんばんは。あの後多少安定して進んでいましたが、また問題が発生しました。
問題と言うのは[基礎からのAndroidプログラミング]にてリストビューのカスタマイズを絡めたTwitterのアプリケーション(ただしパブリックタイムラインが廃止されたので擬似ですが)
を作成、実行後にメインアクティビティのonCreateすら通らずに、ActivityThread.javaの2195行目で例外処理が発生して強制終了してしまう問題です。
ActivityThreadは非常に大きいプログラムのようなのでそれ以外のソースを提示します。

TwitterActivity.java

コード:

package jp.denpa.twitterdammy;

import android.os.Bundle;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import android.util.Log;
import android.widget.ListView;

import android.view.View;
import android.widget.AdapterView;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.ListActivity;

public class TwitterActivity extends ListActivity implements AdapterView.OnItemLongClickListener{

	private static final String PROFILE_IMAGE_URL = "profile_image_url";
	private static final String SCREEN_NAME = "screen_name";
	private static final String TEXT = "text";
	private static final String STATUS = "status";
	private static final String TIMELINE = "http://www.geocities.jp/chopper1250/public_timeline.xml";
	
	private TweetAdapter mAdapter;
	ArrayList<Status> mList;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		mList = parseTimeline();
		if(mList != null){
			mAdapter = new TweetAdapter(this, mList);
			setListAdapter(mAdapter);
			getListView().setOnItemLongClickListener(this);
		}else{
			Log.e("TwetterActivity", "タイムライン取得エラー");
		}
	}
	
	//パブリックタイムラインを表示する
	private ArrayList<Status> parseTimeline(){
		ArrayList<Status> list = null;
		try{
			XmlPullParser xmlPullParser = XmlPullParserFactory.newInstance().newPullParser();
			URL url = new URL(TIMELINE);
			URLConnection connection = url.openConnection();
			xmlPullParser.setInput(connection.getInputStream(), "UTF-8");
			String name;
			Status status = null;
			int eventType = xmlPullParser.getEventType();
			while(eventType != XmlPullParser.END_DOCUMENT){
				switch(eventType){
					case XmlPullParser.START_DOCUMENT:
						list = new ArrayList<Status>();
						break;
					case XmlPullParser.START_TAG:
						name = xmlPullParser.getName();
						if(status.equals(name)){
							status = new Status();
						}else if(status != null){
							if(TEXT.equalsIgnoreCase(name)){
								status.setText(xmlPullParser.nextText());
							}else if(SCREEN_NAME.equalsIgnoreCase(name)){
								status.setScreenName(xmlPullParser.nextText());
							}else if(PROFILE_IMAGE_URL.equalsIgnoreCase(name)){
								status.setProfileImageUrl(xmlPullParser.nextText());
							}
						}
						break;
					case XmlPullParser.END_TAG:
						name = xmlPullParser.getName();
						if(STATUS.equalsIgnoreCase(name)){
							if(list != null && status != null){
								list.add(status);
								status = null;
							}
						}
						break;
				}
				eventType = xmlPullParser.next();
			}
		}catch(MalformedURLException e){
			Log.e("XmlPullParserSampleUrl",e.toString());			
		}catch(XmlPullParserException e){
			Log.e("XmlPullParserSampleUrl",toString());
		}catch(IOException e){
			Log.e("XmlPullParserSampleUrl",e.toString());
		}
		return list;
	}
	
	

	//項目をタップしたときの処理
	@Override
	public void onListItemClick(ListView l, View v, int position, long id){
		Status status = new Status();
		status.setText("new data");
		status.setScreenName("new name");
		mAdapter.add(status);
	}
	
	//項目を長押しした時の処理
	public boolean onItemLongClick(AdapterView<?> adapter, View view, int position, long id){
		Status status = mAdapter.getItem(position);
		mAdapter.remove(status);
		return true;
	}
}
Status.java

コード:

package jp.denpa.twitterdammy;

public class Status {
	private String text;
	private String screenName;
	private String profileImageUrl;
	
	public String getText(){
		return text;
	}
	
	public void setText(String text){
		this.text=text;
	}
	
	public String getScreenName(){
		return screenName;
	}
	
	public void setScreenName(String screenName){
		this.screenName = screenName;
	}
	
	public String getProfileImageUrl(){
		return profileImageUrl;
	}
	
	public void setProfileImageUrl(String profileImageUrl){
		this.profileImageUrl = profileImageUrl;
	}
	
	@Override
	public String toString(){
		return screenName;
	}
}
TwitterAdapter.java

コード:

package jp.denpa.twitterdammy;

import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

//リスト項目内のビューを保持するためのクラス
class ViewHolder{
	ImageView image;
	TextView screenName;
	TextView text;
}

public class TweetAdapter extends ArrayAdapter<Status> {
	private LayoutInflater mInflater;
	
	//コンストラクタ
	public TweetAdapter(Context context, List<Status> objects){
		super(context, 0, objects);
		mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	}
	
	//リストの項目(1行)を作成する処理
	@Override
	public View getView(int position, View convertView, ViewGroup parent){
		ViewHolder holder;
		if(convertView == null){
			//ビューが無ければ作成
			convertView = mInflater.inflate(R.layout.costom_list_cell, parent, false);
			holder = new ViewHolder();
			holder.image = (ImageView) convertView.findViewById(R.id.image);
			holder.screenName = (TextView) convertView.findViewById(R.id.screen_name);
			holder.text = (TextView) convertView.findViewById(R.id.text);
			convertView.setTag(holder);			
		}else{
			//ビューがあれば再利用
			holder = (ViewHolder) convertView.getTag();
		}
		//項目内の各ビューに値をセットする
		Status status = getItem(position);
		holder.screenName.setText(status.getScreenName());
		holder.text.setText(status.getText());
		return convertView;
	}
}
ActivityThread.java(例外が起きた場所のみ一部抜粋)

コード:

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        ComponentName component = r.intent.getComponent();
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }

        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }

        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
            if (localLOGV) Slog.v(
                    TAG, r + ": app=" + app
                    + ", appName=" + app.getPackageName()
                    + ", pkg=" + r.packageInfo.getPackageName()
                    + ", comp=" + r.intent.getComponent().toShortString()
                    + ", dir=" + r.packageInfo.getAppDir());

            if (activity != null) {
                Context appContext = createBaseContextForActivity(r, activity);
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                        + r.activityInfo.name + " with config " + config);
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                activity.mStartedActivity = false;
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }

                activity.mCalled = false;
                mInstrumentation.callActivityOnCreate(activity, r.state);
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onCreate()");
                }
                r.activity = activity;
                r.stopped = true;
                if (!r.activity.mFinished) {
                    activity.performStart();
                    r.stopped = false;
                }
                if (!r.activity.mFinished) {
                    if (r.state != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                    }
                }
                if (!r.activity.mFinished) {
                    activity.mCalled = false;
                    mInstrumentation.callActivityOnPostCreate(activity, r.state);
                    if (!activity.mCalled) {
                        throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                            " did not call through to super.onPostCreate()");
                    }
                }
            }
            r.paused = true;

            mActivities.put(r.token, r);

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {                //------------------------------------------------------ここで例外発生
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }

        return activity;
    }
吐いたエラー
java.lang.RuntimeException: Unable to start activity ComponentInfo{jp.denpa.twitterdammy/jp.denpa.twitterdammy.TwitterActivity}: java.lang.NullPointerException

NullPointerって言っているのはわかるんですがね・・・

YuO
記事: 947
登録日時: 14年前
住所: 東京都世田谷区

Re: android twitter リストビューにてActivityThreadで例外が発生する

#2

投稿記事 by YuO » 10年前

ちゃんとデバッグしましょう。
例えば,例外のオブジェクトのjava.lang.Exception#getStackTraceや,同#printStackTraceを見て実際にNullPoiinterExceptionが発生する場所を調べるとか,
デバッガでtryブロックの先頭にブレイクポイントを置いて一行ずつステップ実行してみるとか。

NullPointerExceptionの主たる原因は,
  • インスタンスメソッドを呼び出す時に,呼び出し元オブジェクトがnullである
  • nullを許容しない引数にnullを渡した
です。
実際にNullPointerExceptionの発生する箇所を調べ,その時の呼び出し元オブジェクトやメソッドの引数がちゃんとオブジェクトインスタンスを指しているか調べ,
指していないのであればその値を生成しているはずの場所で正しく起きていない原因を調べる,ということを行っていく必要があります。

LL

Re: android twitter リストビューにてActivityThreadで例外が発生する

#3

投稿記事 by LL » 10年前

書き忘れた私が悪いのですが、ブレークポイントについて実際に試そうとはしたのですがブレークポイントを置こうとしても置けませんでした。(実際に置こうとした場所は一番最初にエラーの起きたActivityThread.java内です)
恐らくデフォルトで用意されている物にはブレークポイントは使えないのでしょうかね。
どこに置こうとしても配置できませんでしたし、メソッド部分からみようとしても『メソッドブレークポイントを作成できません。 メソッドシグネチャーが使用不可能です』
と言われて弾かれますし。

それ以外でもブレイクポイントを置いて1行ずつデバッグしようとする行為は投稿前に試しています。
(メインアクティビティのonCreateなどといった最初に呼ばれる箇所に置いたのですが、そこすら通る前にActivityThreadで引っかかりましたから・・・)

LL

Re: android twitter リストビューにてActivityThreadで例外が発生する

#4

投稿記事 by LL » 10年前

よ・・・ようやく分かりました・・・・
例外を吐いたactivityの中身をみたらmAdapterがnullだったので調べてみると
下記サイトにて
http://d.hatena.ne.jp/language_and_engi ... 0111013/p1
ListView内の要素がnullだった模様です。
そこで該当部分の初期化を行うメソッドを見ると、

コード:

package jp.denpa.twitterdammy;

import android.os.Bundle;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import android.util.Log;
import android.widget.ListView;

import android.view.View;
import android.widget.AdapterView;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.ListActivity;

public class TwitterActivity extends ListActivity implements AdapterView.OnItemLongClickListener{

	private static final String PROFILE_IMAGE_URL = "profile_image_url";
	private static final String SCREEN_NAME = "screen_name";
	private static final String TEXT = "text";
	private static final String STATUS = "status";
	private static final String TIMELINE = "http://www.geocities.jp/chopper1250/public_timeline.xml";
	
	private TweetAdapter mAdapter;
	ArrayList<Status> mList;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		mList = parseTimeline();
		if(mList != null){
			mAdapter = new TweetAdapter(this, mList);						
			setListAdapter(mAdapter);
			getListView().setOnItemLongClickListener(this);
		}else{
			Log.e("TwetterActivity", "タイムライン取得エラー");
		}
	}
	
	//パブリックタイムラインを表示する
	private ArrayList<Status> parseTimeline(){
		ArrayList<Status> list = null;
		try{
			XmlPullParser xmlPullParser = XmlPullParserFactory.newInstance().newPullParser();
			URL url = new URL(TIMELINE);
			URLConnection connection = url.openConnection();
			xmlPullParser.setInput(connection.getInputStream(), "UTF-8");
			String name;
			Status status = null;
			int eventType = xmlPullParser.getEventType();
			while(eventType != XmlPullParser.END_DOCUMENT){
				switch(eventType){
					case XmlPullParser.START_DOCUMENT:
						list = new ArrayList<Status>();
						break;
					case XmlPullParser.START_TAG:
						name = xmlPullParser.getName();
						if(STATUS.equalsIgnoreCase(name)){						//-----------------status.equals(name)になってた。
							status = new Status();
						}else if(status != null){
							if(TEXT.equalsIgnoreCase(name)){
								status.setText(xmlPullParser.nextText());
							}else if(SCREEN_NAME.equalsIgnoreCase(name)){
								status.setScreenName(xmlPullParser.nextText());
							}else if(PROFILE_IMAGE_URL.equalsIgnoreCase(name)){
								status.setProfileImageUrl(xmlPullParser.nextText());
							}
						}
						break;
					case XmlPullParser.END_TAG:
						name = xmlPullParser.getName();
						if(STATUS.equalsIgnoreCase(name)){
							if(list != null && status != null){
								list.add(status);
								status = null;
							}
						}
						break;
				}
				eventType = xmlPullParser.next();
			}
		}catch(MalformedURLException e){
			Log.e("XmlPullParserSampleUrl",e.toString());			
		}catch(XmlPullParserException e){
			Log.e("XmlPullParserSampleUrl",toString());
		}catch(IOException e){
			Log.e("XmlPullParserSampleUrl",e.toString());
		}
		return list;
	}
	
	

	//項目をタップしたときの処理
	@Override
	public void onListItemClick(ListView l, View v, int position, long id){
		Status status = new Status();
		status.setText("new data");
		status.setScreenName("new name");
		mAdapter.add(status);
	}
	
	//項目を長押しした時の処理
	public boolean onItemLongClick(AdapterView<?> adapter, View view, int position, long id){
		Status status = mAdapter.getItem(position);
		mAdapter.remove(status);
		return true;
	}
}
注釈文の箇所
if(STATUS.equalsIgnoreCase(name)){
が間違ってました・・・
参考書どおりに進めたのが仇になった・・・(勘違いしやすいメンバ名前つけんじゃねーよ!)
ちょっと可読性が下がってもはっきりと打ち間違えや読み間違えをしない様な名前をつけるべきでしたね・・・
あとIDEの変換候補に頼るのは止めた方がいいですね。あまり頼りすぎると似た名前のメソッドなどを気付かずに使用してしまう可能性があるみたいです。
長くなるので次で完成したコードを張り、解決にチェックさせていただきます。

LL

Re: android twitter リストビューにてActivityThreadで例外が発生する

#5

投稿記事 by LL » 10年前

完成コード

TwitterActivity.java

コード:

package jp.denpa.twitterdammy;

import android.os.Bundle;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import android.util.Log;
import android.widget.ListView;

import android.view.View;
import android.widget.AdapterView;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.ListActivity;

public class TwitterActivity extends ListActivity implements AdapterView.OnItemLongClickListener{

	private static final String PROFILE_IMAGE_URL = "profile_image_url";
	private static final String SCREEN_NAME = "screen_name";
	private static final String TEXT = "text";
	private static final String STATUS = "status";
	private static final String TIMELINE = "http://www.geocities.jp/chopper1250/public_timeline.xml";
	
	private TweetAdapter mAdapter;
	ArrayList<Status> mList;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		mList = parseTimeline();
		if(mList != null){
			mAdapter = new TweetAdapter(this, mList);						
			setListAdapter(mAdapter);
			getListView().setOnItemLongClickListener(this);
		}else{
			Log.e("TwetterActivity", "タイムライン取得エラー");
		}
	}
	
	//パブリックタイムラインを表示する
	private ArrayList<Status> parseTimeline(){
		ArrayList<Status> list = null;
		try{
			XmlPullParser xmlPullParser = XmlPullParserFactory.newInstance().newPullParser();
			URL url = new URL(TIMELINE);
			URLConnection connection = url.openConnection();
			xmlPullParser.setInput(connection.getInputStream(), "UTF-8");
			String name;
			Status status = null;
			int eventType = xmlPullParser.getEventType();
			while(eventType != XmlPullParser.END_DOCUMENT){
				switch(eventType){
					case XmlPullParser.START_DOCUMENT:
						list = new ArrayList<Status>();
						break;
					case XmlPullParser.START_TAG:
						name = xmlPullParser.getName();
						if(STATUS.equalsIgnoreCase(name)){						//-----------------status.equals(name)になってた。
							status = new Status();
						}else if(status != null){
							if(TEXT.equalsIgnoreCase(name)){
								status.setText(xmlPullParser.nextText());
							}else if(SCREEN_NAME.equalsIgnoreCase(name)){
								status.setScreenName(xmlPullParser.nextText());
							}else if(PROFILE_IMAGE_URL.equalsIgnoreCase(name)){
								status.setProfileImageUrl(xmlPullParser.nextText());
							}
						}
						break;
					case XmlPullParser.END_TAG:
						name = xmlPullParser.getName();
						if(STATUS.equalsIgnoreCase(name)){
							if(list != null && status != null){
								list.add(status);
								status = null;
							}
						}
						break;
				}
				eventType = xmlPullParser.next();
			}
		}catch(MalformedURLException e){
			Log.e("XmlPullParserSampleUrl",e.toString());			
		}catch(XmlPullParserException e){
			Log.e("XmlPullParserSampleUrl",toString());
		}catch(IOException e){
			Log.e("XmlPullParserSampleUrl",e.toString());
		}
		return list;
	}
	
	

	//項目をタップしたときの処理
	@Override
	public void onListItemClick(ListView l, View v, int position, long id){
		Status status = new Status();
		status.setText("new data");
		status.setScreenName("new name");
		mAdapter.add(status);
	}
	
	//項目を長押しした時の処理
	public boolean onItemLongClick(AdapterView<?> adapter, View view, int position, long id){
		Status status = mAdapter.getItem(position);
		mAdapter.remove(status);
		return true;
	}
}
Status.java

コード:

package jp.denpa.twitterdammy;

public class Status {
	private String text;
	private String screenName;
	private String profileImageUrl;
	
	public String getText(){
		return text;
	}
	
	public void setText(String text){
		this.text=text;
	}
	
	public String getScreenName(){
		return screenName;
	}
	
	public void setScreenName(String screenName){
		this.screenName = screenName;
	}
	
	public String getProfileImageUrl(){
		return profileImageUrl;
	}
	
	public void setProfileImageUrl(String profileImageUrl){
		this.profileImageUrl = profileImageUrl;
	}
	
	@Override
	public String toString(){
		return screenName;
	}
}
TwittetAdapter.java

コード:

package jp.denpa.twitterdammy;

import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

//リスト項目内のビューを保持するためのクラス
class ViewHolder{
	ImageView image;
	TextView screenName;
	TextView text;
}

public class TweetAdapter extends ArrayAdapter<Status> {
	private LayoutInflater mInflater;
	
	//コンストラクタ
	public TweetAdapter(Context context, List<Status> objects){
		super(context, 0, objects);
		mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	}
	
	//リストの項目(1行)を作成する処理
	@Override
	public View getView(int position, View convertView, ViewGroup parent){
		ViewHolder holder;
		if(convertView == null){
			//ビューが無ければ作成
			convertView = mInflater.inflate(R.layout.costom_list_cell, parent, false);
			holder = new ViewHolder();
			holder.image = (ImageView) convertView.findViewById(R.id.image);
			holder.screenName = (TextView) convertView.findViewById(R.id.screen_name);
			holder.text = (TextView) convertView.findViewById(R.id.text);
			convertView.setTag(holder);			
		}else{
			//ビューがあれば再利用
			holder = (ViewHolder) convertView.getTag();
		}
		//項目内の各ビューに値をセットする
		Status status = getItem(position);
		holder.screenName.setText(status.getScreenName());
		holder.text.setText(status.getText());
		return convertView;
	}
}
costom_list_cell.xml(Layout)

コード:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" >
    
    <ImageView
        android:id="@+id/image"
        android:layout_width="50dp"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher"
        android:contentDescription="launcher"/>
    
    <LinearLayout 
[code=xml]
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<TextView
android:id="@+id/screen_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="TextView"
android:textSize="20sp"/>

<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="TextView"
android:textColor="#505050"/>
</LinearLayout>
</LinearLayout>
[/code]

main.xml (Layout)

コード:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">
    
    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
    </ListView>
</LinearLayout>

閉鎖

“C言語何でも質問掲示板” へ戻る