I have read several SO posts that has the same questions as I do:
- When I add a OnClickListener for a View (in this case an EditText) inside the Fragment class, the click event is never fired.
- If I move the code away from the Fragment class and move it into the Activity instead, the click event is fired correctly.
The other SO questions ask the same question, but the solutions they have (if any) does not apply to my situation, from what I can tell. Therefore, I am asking this question "again".
First, the fragment_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="se.snapcode.lanstrafiken.MainActivityFragment">
<LinearLayout
android:focusable="true" android:focusableInTouchMode="true"
android:layout_width="0px" android:layout_height="0px"/>
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textPostalAddress"
android:ems="15"
android:id="@+id/editTextFrom"
android:hint="From"
android:layout_alignParentEnd="true"
android:focusableInTouchMode="false"
android:clickable="true"
android:layout_marginBottom="20sp"
/>
</LinearLayout>
And now the MainActivityFragment.java:
public class MainActivityFragment extends Fragment {
public MainActivityFragment() { }
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View myView = inflater.inflate(R.layout.fragment_main, container, false);
EditText ed1 = (EditText) myView.findViewById(R.id.editTextFrom);
ed1.setText("This is a test");
ed1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("Snapcode", "Test 1 2 3");
Toast.makeText(v.getContext(), "test", Toast.LENGTH_LONG).show();
}
});
EditText ed2 = (EditText) myView.findViewById(R.id.editTextTo);
ed1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
return myView;
}
}
When I click the EditText, the Log.d(...) does not show in the logcat at all, and the Toast isn't displayed.
Now, if I remove everything that has to do with the EditText from the Fragment, and place it in the Activity instead, it works:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar1);
setSupportActionBar(toolbar);
EditText ed1 = (EditText) findViewById(R.id.editTextFrom);
ed1.setText("Test again");
ed1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("Snapcode", "Test from Activity");
Toast.makeText(MainActivity.this, "test", Toast.LENGTH_LONG).show();
}
});
}
// ...
}
Any ideas?
Sidenote
I think its really bad design that Android code isn't "encapsulated". As you can see above, I can access controls inside the Fragment from outside the Fragment, as if the controls are all in the same scope. The R.id.editTextFrom is available everywhere, which I find disturbing. It should only be available inside the Fragment, unless you explicitly make it "public". Compare with UserControls in .NET - there the UserControls are truly stand-alone.
I haven't tried, but what happens if two separate fragments have the same id for a control? Smells like how the web currently works (and what WebComponents are trying to solve).