I am new to Android and am trying to understand the compound view concept if android. I am not sure that my below implementation is practical or not but it is for learning purpose and i have taken this idea from Wrox Android book. So, i have three components i.e a button, a edit text and a list view. The purpose of edit text is to write some text, while the list gets updated with the text and the button is the clear button and it is suppose to clear the edit text. What i am planning to do is to keep the clear button and edit text in one view group. Below it the java and xml code for it.
public class CompoundView extends LinearLayout {
EditText editText;
Button clearButton;
public CompoundView (Context context, AttributeSet attr) {
super(context, attr);
String infService = Context.LAYOUT_INFLATER_SERVICE;
LayoutInflater li;
li = (LayoutInflater)getContext().getSystemService(infService);
li.inflate(R.layout.clearable_edit_text, this, true);
editText = (EditText) findViewById(R.id.editText);
clearButton = (Button) findViewById(R.id.clearButton);
hookUpButton ();
}
public void hookUpButton () {
clearButton.setOnClickListener(new Button.OnClickListener () {
public void onClick (View v) {
editText.setText ("");
}
});
}
public EditText getEditText() {
return this.editText;
}
}
XML
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/clearButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Clear"
/>
</merge>
I have a strong feeling that this implementation is fine. In the next part I have the MainActivity.java and activity_main.xml. In this i am facing the problem and am most probably doing some thing wrong.
public class MainActivity extends Activity {
@SuppressLint({ "ParserError", "ParserError" })
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView myListView = (ListView)findViewById(R.id.myListView);
final CompoundView textAndClear = (CompoundView) findViewById(R.id.myEditAndClear) ;
final EditText editText = textAndClear.getEditText();
final ArrayList<String> toDoItems = new ArrayList<String>();
final ArrayAdapter<String> aa;
int resId = R.layout.todolist_item;
aa= new ArrayAdapter<String> (this, resId, toDoItems);
myListView.setAdapter(aa);
editText.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(event.getAction() == KeyEvent.ACTION_DOWN)
if ((keyCode == KeyEvent.ACTION_DOWN) || (keyCode == KeyEvent.KEYCODE_ENTER)){
toDoItems.add(0,editText.getText().toString());
aa.notifyDataSetChanged();
editText.setText("");
return true;
}
return false;
}
});
}
}
and the 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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.wroxexample.CompoundView
android:id="@+id/myClearableEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<ListView
android:id="@+id/myListView"
android:layout_below="@+id/myEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
and the error is
06-29 06:32:11.783: E/AndroidRuntime(5413): FATAL EXCEPTION: main
06-29 06:32:11.783: E/AndroidRuntime(5413): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.wroxexample/com.example.wroxexample.MainActivity}: android.view.InflateException: Binary XML file line #8: Error inflating class com.example.wroxexmple.CompoundView
06-29 06:32:11.783: E/AndroidRuntime(5413): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
06-29 06:32:11.783: E/AndroidRuntime(5413): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
06-29 06:32:11.783: E/AndroidRuntime(5413): at android.app.ActivityThread.access$600(ActivityThread.java:123)
06-29 06:32:11.783: E/AndroidRuntime(5413): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
06-29 06:32:11.783: E/AndroidRuntime(5413): at android.os.Handler.dispatchMessage(Handler.java:99)
06-29 06:32:11.783: E/AndroidRuntime(5413): at android.os.Looper.loop(Looper.java:137)
06-29 06:32:11.783: E/AndroidRuntime(5413): at android.app.ActivityThread.main(ActivityThread.java:4424)
06-29 06:32:11.783: E/AndroidRuntime(5413): at java.lang.reflect.Method.invokeNative(Native Method)
06-29 06:32:11.783: E/AndroidRuntime(5413): at java.lang.reflect.Method.invoke(Method.java:511)
06-29 06:32:11.783: E/AndroidRuntime(5413): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
06-29 06:32:11.783: E/AndroidRuntime(5413): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
06-29 06:32:11.783: E/AndroidRuntime(5413): at dalvik.system.NativeStart.main(Native Method)
06-29 06:32:11.783: E/AndroidRuntime(5413): Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class com.example.wroxexmple.CompoundView
06-29 06:32:11.783: E/AndroidRuntime(5413): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:691)
06-29 06:32:11.783: E/AndroidRuntime(5413): at android.view.LayoutInflater.rInflate(LayoutInflater.java:739)
06-29 06:32:11.783: E/AndroidRuntime(5413): at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
06-29 06:32:11.783: E/AndroidRuntime(5413): at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
06-29 06:32:11.783: E/AndroidRuntime(5413): at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
06-29 06:32:11.783: E/AndroidRuntime(5413): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:251)
06-29 06:32:11.783: E/AndroidRuntime(5413): at android.app.Activity.setContentView(Activity.java:1835)
06-29 06:32:11.783: E/AndroidRuntime(5413): at com.example.wroxexample.MainActivity.onCreate(MainActivity.java:20)
06-29 06:32:11.783: E/AndroidRuntime(5413): at android.app.Activity.performCreate(Activity.java:4465)
06-29 06:32:11.783: E/AndroidRuntime(5413): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
06-29 06:32:11.783: E/AndroidRuntime(5413): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
06-29 06:32:11.783: E/AndroidRuntime(5413): ... 11 more
06-29 06:32:11.783: E/AndroidRuntime(5413): Caused by: java.lang.ClassNotFoundException: com.example.wroxexmple.CompoundView
06-29 06:32:11.783: E/AndroidRuntime(5413): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
06-29 06:32:11.783: E/AndroidRuntime(5413): at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
06-29 06:32:11.783: E/AndroidRuntime(5413): at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
06-29 06:32:11.783: E/AndroidRuntime(5413): at android.view.LayoutInflater.createView(LayoutInflater.java:552)
06-29 06:32:11.783: E/AndroidRuntime(5413): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:680)
06-29 06:32:11.783: E/AndroidRuntime(5413): ... 21 more
Below the error you posted should be the real cause for the exception. My guess, after a simple look at your code, is that the exception comes from the fact that you only implemented the constructor that takes a
Context(this constructor would normally be used when you instantiate theViewin code). As you use the compound view in a xml layout the constructor that also takes anAttributeSetwill be used(instead of the one you implemented that only takes aContext).Also, as a side note you search for your compound
Viewin theonCreatemethod and you cast it to aLinearLayout. In theonKeycallback you then try to call thegetText()andsetText()on it, methods which are not implemented for the classLinearLayout(you maybe had them in your custom view but if you cast the view as aLinearLayoutthe methods will not be available).Also you might want to read on the
mergetag to improve the layout for your compoundView.