1

我正在编辑 csipsimple 应用程序,并且我已将 setContentView 设置为该文件 in_call_main.xml:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/mainFrame"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ViewStub
        android:id="@+id/dropZones"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout="@layout/in_call_drop_zones" />

    <LinearLayout
        android:id="@+id/inCallContainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dip"
            android:layout_weight="3"
            android:orientation="horizontal" >

            <!--
                Can we do better than using two linear layouts here?
                The problem is that RelativeLayout doesn't allow to use weight and
                plays bad with hidden childs and above/below only support one id
            -->
            <!-- Grid for active calls -->

            <com.csipsimple.ui.incall.InCallInfoGrid
                android:id="@+id/activeCallsGrid"
                android:layout_width="0dip"
                android:layout_height="match_parent"
                android:layout_weight="2"
                android:paddingBottom="4dip"
                android:paddingTop="4dip"
                tools:ignore="NestedWeights" />

            <!-- Grid for held calls -->

            <com.csipsimple.ui.incall.InCallInfoGrid
                android:id="@+id/heldCallsGrid"
                android:layout_width="0dip"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="@drawable/in_call_held_background"
                android:padding="4dip"
                android:visibility="gone" />
        </LinearLayout>

        <!-- Answer slider/buttons -->

        <com.csipsimple.ui.incall.locker.InCallAnswerControls
            android:id="@+id/inCallAnswerControls"
            android:layout_width="match_parent"
            android:layout_height="0dip"
            android:layout_weight="2"
            android:visibility="gone" />

        <!-- Wraps split action bar manually managed -->

        <com.csipsimple.ui.incall.InCallControls
            android:id="@+id/inCallControls"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/incall_bottom_bar_bg" />
    </LinearLayout>

    <com.csipsimple.ui.incall.locker.ScreenLocker
        android:id="@+id/lockerOverlay"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#8000"
        android:visibility="gone" >

    </com.csipsimple.ui.incall.locker.ScreenLocker>



</RelativeLayout>

还有一个布局文件,in_call_card.xml;使用此代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/call_card_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFFFFF"
    android:padding="2dip"
    tools:ignore="Overdraw" >

    <com.csipsimple.widgets.MaxScaleImageView
        android:id="@+id/contact_photo"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/call_action_bar"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:contentDescription="@string/empty_description"
        android:scaleType="centerCrop"
        android:src="@drawable/ic_contact_picture_180_holo_light" /> 

    <RelativeLayout
        android:id="@+id/contact_name_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#9e808080"
        android:gravity="center_vertical" >
  <!--     
            <EditText
        android:id="@+id/editText1"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:ems="10" >



        <requestFocus />
        </EditText>
       --> 

        <com.csipsimple.widgets.MarqueeTextView
            android:id="@+id/contact_name_display_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentRight="true"
            android:ellipsize="marquee"
            android:marqueeRepeatLimit="marquee_forever"
            android:padding="5dip"
            android:singleLine="true"
            android:textColor="@android:color/white"
            android:textSize="25sp" />

        <com.csipsimple.widgets.MarqueeTextView
            android:id="@+id/contact_name_sip_address"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentRight="true"
            android:layout_below="@+id/contact_name_display_name"
            android:ellipsize="marquee"
            android:marqueeRepeatLimit="marquee_forever"
            android:padding="2dip"
            android:singleLine="true"
            android:textColor="@android:color/white"
            android:textSize="15sp" />

        <Chronometer
            android:id="@+id/elapsedTime"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:textSize="20sp" />


    </RelativeLayout>

    <TextView
        android:id="@+id/call_status_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/contact_name_bar"
        android:layout_marginTop="1dip"
        android:background="#c818617b"
        android:gravity="center_vertical|right"
        android:padding="3dip"
        android:text="@string/call_state_calling"
        android:textAllCaps="true"
        android:textColor="@android:color/white"
        android:textSize="15sp" />

    <RelativeLayout
        android:id="@+id/call_secure_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/call_status_text"
        android:layout_marginTop="1dip"
        android:background="#c8d4aa00" >


        <ImageView
            android:id="@+id/call_secure_icon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_margin="2dip"
            android:contentDescription="@string/empty_description"
            android:src="@drawable/stat_sys_vp_phone_call" />

        <TextView
            android:id="@+id/call_secure_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_toRightOf="@+id/call_secure_icon"
            android:padding="2dip"
            android:textColor="@android:color/white"
            android:textSize="15sp" />
    </RelativeLayout>

    <FrameLayout
        android:id="@+id/call_action_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/end_call_bar"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignWithParentIfMissing="true"
        android:layout_marginTop="2dip"
        android:background="#000000" />

    <LinearLayout


        android:id="@+id/end_call_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_marginTop="2dip"
        android:background="@drawable/end_call_background"
        android:orientation="horizontal" >

        <!--   android:onClick="pushtotalk3" -->
         <ToggleButton
            android:id="@+id/PTT_button5"
            android:layout_width="0dp"
            android:layout_height="fill_parent"            
            android:text="@string/ptt5" 
            android:layout_weight="50"
            android:textOn="Push To Talk On"
            android:textOff="Push To Talk Off"
            android:background="@drawable/btn_lightblue_glossy"
            android:textColor="@android:color/white"
            android:textSize="15sp"
            />      

        <ImageButton
            android:id="@+id/endButton"
            style="?attr/actionButtonStyle"
            android:layout_width="0dp"
            android:layout_height="fill_parent"
            android:layout_weight="50"
            android:contentDescription="@string/done"
            android:minHeight="64dip"
            android:src="@drawable/ic_end_call" />


    </LinearLayout>


</RelativeLayout>

当我 setContentView 到另一个 xml 文件时,我仍然可以看到这个文件中的元素,我不确定它是如何工作的。正如我可以看到PTT_button5按钮等,我的问题是如果我想在这个按钮上设置一个监听器,我该怎么做?如果我尝试引用它,我会得到一个空指针异常:

findViewById(R.id.PTT_button5).setOnTouchListener(this);

这是因为我将 setContentView 设置为一个不包含对这个按钮的引用的文件,那么我如何获得对这个按钮的引用呢?我也不确定这是如何工作的,因为在没有将ContentView 设置为该文件的情况下,按钮显示在屏幕上。

编辑:当按钮在屏幕上时,任何人都可以从代码中看到它是如何完成的吗? https://code.google.com/p/csipsimple/source/browse/trunk/CSipSimple/src/com/csipsimple/ui/incall/?r=2170

4

2 回答 2

2

我认为您需要了解以下基础知识:

1) Activity为您提供一个窗口,您可以在其中放置您的 UIsetContentView(View)

在您的情况下,这View(让我们称之为contentView)使用膨胀in_call_main.xml

2)包含contentView其他视图。

在您的情况下,contentView包含在 XML 布局中定义的视图。这就是在活动开始时显示它们的原因。(如果 xml 文件为空,则看不到任何内容)

3您可以从contentView.

这意味着,使用代码,我们可以创建一个新视图(比如说ToggleButton)并将其添加到contentView. 这ToggleButton现在在屏幕上可见。(因为它是 的孩子contentView)。同样,删除子视图会导致它消失。

4)任何视图(不仅仅是contentView)都可以从布局文件中膨胀(创建)。

在您的情况下,InCallCard是一个视图,它从in_call_card.xml.

当调用 ..的getView()方法时,会创建并返回 (view) 的新实例。然后将其附加到,因此 ( ) 内的所有 UI 元素(视图)现在都可以在屏幕上看到。(包括那些让你很困扰的)CallsAdapterInCallCardcontentViewInCallCardin_call_card.xmlToggleButton

因此,如果您尝试访问ToggleButtonfromonCreate()它将为空。它还没有被添加到contentView。但是,如果您在getView方法中执行相同的操作,正如我在另一个答案中所解释的那样。您将看到它不再为空,您可以附加侦听器、更改背景等。

于 2013-11-05T06:10:29.603 回答
0

这是因为我将 setContentView 设置为不包含对此按钮的引用的文件。

是的。findviewById查找具有当前膨胀布局中提到的 id 的视图。因此,如果您将布局的内容设置为活动,它会查找具有该布局中提到的 id 的视图。如果不是你的初始化失败,你会得到NullPointerException.

你说

我已经 setContentView 到这个文件,in_call_main.xml

所以

  setContentView(R.layout.in_call_main);
  findViewById(R.id.PTT_button5).setOnTouchListener(this);// gives NPE
  //in_call_main.xml does not have a toogle button with id button5 

in_call_card.xml你有

  <ToggleButton
        android:id="@+id/PTT_button5"

但如果你有

  setContentView(R.layout.in_call_card);
  findViewById(R.id.PTT_button5).setOnTouchListener(this);// works
  // in_call_card.xml has a toogle button with id button5

那么如何获得对这个按钮的引用呢?

你不能不夸大布局。

于 2013-10-29T10:44:34.127 回答