I am totaly new to java and android. I have the following UI setup:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
...
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="0dp"
...>
<LinearLayout
android:id="#+id/linLay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
During runtime, some TextViews will be added to the LinearLayout. I have following problem. The phone filps, the dynamicaly added TextViews disapeare. The reason ist that the onCreate(Bundle savedInstanceState) method of the activity is called, if you flip your phone.
I setup the following method, to save the instance state (textViews is a member of the Activity class (Vector)):
protected void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
//Save the TextViews
textViews.removeAllElements();
LinearLayout layout = getLinearLayout();
while (layout.getChildCount() > 0)
{
View view = layout.getChildAt(0);
if (view instanceof TextView)
{
layout.removeView(view);
textViews.add((TextView) view);
}
}
state.putSerializable("textViews", textViews);
}
I implemented this cod in the onCreate(Bundle savedInstanceState) method to restore the TextViews:
LinearLayout linLay = getLinearLayout();
//Load TextViews
if ((savedInstanceState != null) && (savedInstanceState.getSerializable("textViews") != null))
{
Serializable serializable = savedInstanceState.getSerializable("textViews");
if (serializable instanceof Vector)
{
textViews= (Vector<TextView>) serializable;
}
}
if (textViews!= null) {
for (TextView textView : textViews) {
linLay.addView(textView);
}
}
This code works for the fliping issue, but it creates a new issue. If I press the home button, I get the following error:
Parcel: unable to marshal value
I read that the problem is that Vector<TextView> is not serializable. But why does fliping the phone does not effect this error? I debugt the app and I am sure, the state.putSerializable(...) method is called, if the phone is fliped.
How would you store a TextView instead? It is not possible to save a String instead of the TextView, because the backgroundResource of the TextViews differ.
I know that this int solution, but hear me out. TextViews are bunch of text on the screen right? my advice would be when activity recreation will happen dont save TextViews as themselves save text thats in the TextView. and after that use them to draw new ones. this is more logical, more optimized and by using ViewModel it can become more elegant by storing that texts in LiveData of List and observing and reacting in activity. here is documentation for it: LiveData and ViewModel
Related
I'm building a chat app in Android Studio with the abitily to send routes on a map. I've implemented this by using a RecyclerView and ViewHolders, which hold the necessary UI with MapViews in lite mode (map:liteMode="true"). Thing is, when I add a map UI element to the recyclerView and scroll to the end by using scrollToPosition(adapter.getItemCount() - 1), the scrolling has trouble following the views and is always slightly off, as seen on the screenshot
(https://i.postimg.cc/BvMzrHJL/Screenshot-20190526-005535.png).
Moreover, the keyboard gets confused about the height of the views as well when clicked (https://i.postimg.cc/Hs6BsHfR/Screenshot-20190526-011647.png).
I have tried switching lite mode off, but it makes the scrolling laggy and handling lifecycle events becomes an issue since my MapViews are in ViewHolders, not in Activities or Fragments, see official documentation:
Users of this class [MapView] must forward all the life cycle methods from the
Activity or Fragment containing this view to the corresponding ones in
this class.
I have also tried changing the height of the layout from android:layout_height="wrap_content" to android:layout_height="250dp", but that also didn't work at all.
Also, scrolling works just fine with Views containing only text or an empty RelativeLayout istead of MapView.
I used this sample from Google's developer documentation https://github.com/googlemaps/android-samples/blob/master/ApiDemos/java/app/src/main/java/com/example/mapdemo/LiteListDemoActivity.java
So here is my ViewHolder (one of two):
private class SentRouteViewHolder extends RecyclerView.ViewHolder implements OnMapReadyCallback
{
MapView sentMap;
TextView routeSentTime;
GoogleMap map;
public SentRouteViewHolder(#NonNull View itemView) {
super(itemView);
sentMap = itemView.findViewById(R.id.sent_map);
routeSentTime = itemView.findViewById(R.id.route_sent_time);
sentMap.onCreate(null);
sentMap.onResume();
sentMap.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
MapsInitializer.initialize(getApplicationContext());
map = googleMap;
setMapRoute();
}
void bind(Message message)
{
sentMap.setTag(message);
setMapRoute();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
routeSentTime.setText(simpleDateFormat.format(message.getTime()));
}
void setMapRoute()
{
if(map == null) return;
Message message = (Message) sentMap.getTag();
if(message==null) return;
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
}
}
And adding the item to the RecyclerView:
activeCollection.add(newMessage).addOnSuccessListener(documentReference -> {
documentReference.get().addOnSuccessListener(documentSnapshot -> {
adapter.addMessage(documentSnapshot);
adapter.notifyItemInserted(adapter.getItemCount());
chatReycler.scrollToPosition(adapter.getItemCount()-1);
});
});
The onBindViewHolder:
SentRouteViewHolder routeViewHolder = (SentRouteViewHolder) viewHolder;
routeViewHolder.bind(message);
The onCreateViewHolder:
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.route_sent,parent,false);
Log.v("measure",String.valueOf(v.getMeasuredHeight()));
return new SentRouteViewHolder(v);
RecyclerView configuration:
manager.setStackFromEnd(true);
chatReycler.setLayoutManager(manager);
chatReycler.setAdapter(adapter);
chatReycler.setHasFixedSize(false);
chatReycler.setRecyclerListener(viewHolder -> {
if(viewHolder.getItemViewType()==ChatRecyclerViewAdapter.VIEW_TYPE_ROUTE_RECEIVED)
{
ChatRecyclerViewAdapter.ReceivedRouteViewHolder holder = (ChatRecyclerViewAdapter.ReceivedRouteViewHolder) viewHolder;
if(holder.map!=null)
{
holder.map.clear();
holder.map.setMapType(GoogleMap.MAP_TYPE_NONE);
}
}
else if (viewHolder.getItemViewType()==ChatRecyclerViewAdapter.VIEW_TYPE_ROUTE_SENT)
{
ChatRecyclerViewAdapter.SentRouteViewHolder holder = (ChatRecyclerViewAdapter.SentRouteViewHolder) viewHolder;
if(holder.map!=null)
{
holder.map.clear();
holder.map.setMapType(GoogleMap.MAP_TYPE_NONE);
}
}
});
The ViewHolder XML file
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:paddingBottom="3dp"
android:layout_marginBottom="13dp">
<ImageView
android:id="#+id/route_received_background"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_marginStart="15dp"
android:src="#drawable/message_received_background"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.gms.maps.MapView
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="#+id/received_map"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="9dp"
app:layout_constraintBottom_toBottomOf="#+id/route_received_background"
app:layout_constraintEnd_toEndOf="#+id/route_received_background"
app:layout_constraintStart_toStartOf="#+id/route_received_background"
app:layout_constraintTop_toTopOf="#+id/route_received_background"
map:mapType="normal"
map:liteMode="true"
/>
<TextView
android:id="#+id/route_received_time"
style="#style/TextAppearance.MaterialComponents.Caption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:textSize="13sp"
app:layout_constraintBottom_toBottomOf="#+id/route_received_background"
app:layout_constraintStart_toEndOf="#+id/route_received_background"
tools:text="11:50" />
</android.support.constraint.ConstraintLayout>
I want the RecyclerView to scroll to the bottom of the sent map, and not to the middle of it. How can I make that happen?
I had a similar problem with scrolling and checked that the parent layout was 0dp high. I changed it to match_parent and it worked.
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
I've already tried searching the Google on how to switch activities in android studio, even in the official documentation with tutorial. I did it exactly like it was said but I am still unable to get redirected to another activity after clicking a button.
I've entered an onClick name of the method to the button
it looks like this: https://i.imgur.com/pmsztaL.png (can't post images yet)
and this is my MainActivity.class file with said method
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void handleButtonAddNew(View view) {
MainActivity.this.startActivity(new Intent(MainActivity.this, AddItemActivity.class));
}
}
After pressing the button in a phone, the button does nothing.
This is my AddItemActivity.class
public class AddItemActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_item);
}
public void handleButtonRemember(View view) {
finish();
}
}
How come the button doesn't work, what did I do wrong?
EDITS
EDIT: Successfully ran emulator and the buttons did in fact work, the problem lies within my phone, the buttons there don't want to work. Where could be the issue now?
EDIT: XML Layout of MainActivity.class
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="#+id/buttonAddNew"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="188dp"
android:layout_marginRight="188dp"
android:layout_marginBottom="264dp"
android:text="#string/buttonAdd"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<ScrollView
android:id="#+id/scrollView2"
android:layout_width="395dp"
android:layout_height="715dp"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</ScrollView>
</android.support.constraint.ConstraintLayout>
EDIT: The problem was with scroll view blocking the clickable button so on my phone the button didn't register any clicks, after removing the scrollview the button works normally.
I'm afraid that this button doesn't get any listeners attached.
The programatic approach
From the Official Android Documentation
I'd suggest you use this in your onCreate callback:
Button button = (Button) findViewById(R.id.your_btn_id);
button.setOnClickListener((view) -> { theMethodYouWantToCallHere(view); });
XML approach
Please double check the following using this approach
Your activity is registered in the AndroidManifest.xml
You're including the android namespace to the XML file in the parent container of the layout file. IE: xmlns:android="http://schemas.android.com/apk/res/android"
Make sure you're setting the content view for the activity with setContentView(R.layout.your_layout_file);
Once 2 is satisfied make sure you're using the android namespace. IE: android:onClick="yourMethod"
As you're currently doing: Make sure the onClick callbacked method has the View view parameter; no more, no less
Make sure the onClick function is public in the activity.
And that no other clickable views are covering the view you're registering the onClick listener for :)
Including the namespace: xmlns:android="http://schemas.android.com/apk/res/android"
XML file
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button android:text="Click me!" android:onClick="clicked" android:layout_height="wrap_content" android:layout_width="wrap_content"/>
</FrameLayout>
The activity
public class MainActivity extends AppCompatActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void clicked(View view){
Toast.makeText(this, "Hey! Im clicked!",Toast.LENGTH_SHORT).show();
}
}
I have an XML layout file that has a TextView within a CoordinatorLayout.
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".SpecificProgramSelectionActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="75dp"
android:id="#+id/saved_program"
android:text="Empty"
android:textAlignment="center"
android:gravity="fill"
android:textSize="20dp"
android:background="#drawable/program_selection_border"
android:textColor="#color/black"
android:clickable="true"
android:focusable="true"
android:onClick="addToSavedPrograms"
android:paddingTop="5dp"
android:paddingBottom="5dp"/>
And this code that inflates the layout and adds it into a Linear Layout in the activity's view.
for (PlayerWithObjectives player : players){
name = player.getName();
for (String objective : player.getObjectives()){
objectives.add(objective);
}
nameView = inflater.inflate(R.layout.inflatable_player_name_view, null);
((TextView)nameView.findViewById(R.id.saved_program)).setText(name);
((TextView)nameView.findViewById(R.id.saved_program)).setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
((TextView)nameView.findViewById(R.id.saved_program)).setTextSize(20);
linearLayout.addView(nameView);
}
(This is the activity's layout XML)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SpecificProgramSelectionActivity"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/specific_program_selection_linear_layout">
</LinearLayout>
</ScrollView>
Everything looks fine in the app when I run it. Every inflated view shows up, the only issue is that the method that I specified in the onClick attribute for the inflated TextView does not get called. Why is that? Here is the method that is supposed to be called
public void addToSavedPrograms(View view){
String name = (String) (((TextView)view.findViewById(R.id.saved_program)).getText());
namesToSend.add(name);
editor.putStringSet("Tracked Players", namesToSend);
editor.commit();
Toast.makeText(getApplicationContext(),name + " was saved to preferences.", Toast.LENGTH_SHORT);
}
Why doesn't the method get called? I already saw all the other threads about using setContent() and stuff but that didn't work and it was not explained that great in the answer. Any help would be greatly appreciated.
public class YourActivity extends AppCompatActivity implements OnClickListener{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textview=(TextView)findViewById(R.id.saved_program);
textview.setOnClickListener(this);
}
#Override
public void onClick(View view) {
switch(view.getId()){
case R.id.saved_program:
//call your function here
default:
break;
}
}
you can do it like this.
Update:
First off, thank you to everybody that commented, your help was greatly appreciated. Your no judgment assistance is an awesome and welcome change from a lot of what I have experienced and seen on in this community.
Secondly, I figured out my issue. Or got my code to work at least. Once I got a better understanding of inflating layouts I changed this line of code
nameView = inflater.inflate(R.layout.inflatable_player_name_view, null);
To
nameView = (TextView) inflater.inflate(R.layout.inflatable_add_player_name_view, linearLayout, false);
The difference is that When you inflate, it returns an object that is the same type as the top parent in the specified layout file (Which in this case is "R.layout.inflatable_player_name_view"). So I changed nameView to a TextView object and cast the returned object as a TextView. Then I specified the wanted parent layout (To get the right layoutParams) and put false so that it does not attach it automatically to that parent layout. After that I simply made the alterations to the textView that I wanted, like setting the text values and whatnot, and then manually added it to the parent linearlayout that I wanted. After doing this there was not even a need to set an onClickListener programmatically because the android:onClick method worked just fine.
EDIT 2:
In my MainActivity I have a function (displayData) that displays the substitutions for my school.
public void displayData(List<Schoolday> results) {
TabLayout mainTabLayout = (TabLayout) findViewById(R.id.mainTabLayout);
ViewPager mainViewPager = (ViewPager) findViewById(R.id.mainViewPager);
// draw the tabs depending on the days from the file
mainTabLayout.removeAllTabs();
for (int n = 0; n < results.size(); n++) {
List<Subject> subjectsToDisplay = new ArrayList<>();
if (myPreferences.getBoolean(SHOW_WHOLE_PLAN, true)) {
subjectsToDisplay = results.get(n).getSubjects();
} else {
List<Subject> tempSubjectsToDisplay;
tempSubjectsToDisplay = results.get(n).getSubjects();
for (int i = 0; i < tempSubjectsToDisplay.size(); i++) {
if (tempSubjectsToDisplay.get(i).getCourse().contains(myPreferences.getString(CLASS_TO_SHOW, "None"))) {
subjectsToDisplay.add(tempSubjectsToDisplay.get(i));
}
}
}
results.get(n).setSubjects(subjectsToDisplay);
// only create a tab if there's any information to show within that tab
if (results.get(n).getSubjects().size() > 0) {
mainTabLayout.addTab(mainTabLayout.newTab().setText(results.get(n).getDate().substring(0, 6)));
}
}
PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager(), mainTabLayout.getTabCount(), results);
mainViewPager.setAdapter(pagerAdapter);
mainViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mainTabLayout));
mainTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
mainViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
This is my main layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.design.widget.TabLayout
android:id="#+id/mainTabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:tabGravity="fill" />
<android.support.v4.view.ViewPager
android:id="#+id/mainViewPager"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="#id/mainTabLayout" />
</RelativeLayout>
And this is the layout of the fragment that represents a page in the ViewPager:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/mainSwipeContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/mainRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
Whenever a refresh is triggered by the SwipeRefreshLayout I need the function displayData to be called.
How can I call this function since the call comes from within a fragment/page from the ViewPager and displayData is not static?
Old question:
I've been searching around quite a while but couldn't find an answer. Maybe I've searched for the wrong thing - just pointing me to that would already help.
My project (Vertretungsplan on github) displays the substitution plan for my school which is available to view/download as an xml file (xml file from school website). I then display the data in my app.
I have a TabLayout (different tabs represent different days) and a connected ViewPager. Each page is using a fragment. Each fragment includes a RecyclerView (to display the results) which is wrapped in a SwipeRefreshLayout.
When I want to refresh the data with the SwipeRefreshLayout I need to download all the data again and then update all the pages as well as the TabLayout(a new day might have a been added so a new tab will be needed). Since my refresh happens inside a fragment but I'm referencing the TabLayout as well as the ViewPager from my MainActivity I have no clue how to properly access all the elements in order to update the content.
My idea was to set up a Broadcast to let my MainActivity know that it needs to refresh the page since it originally set up the whole layout but maybe there is a better solution for that?
I'm kinda new to stackoverflow so feel free to correct me in the way of asking things here! If there's anything other information you need just ask me!
I appreciate your help!!
There are a couple ways to implement what you are asking. The most direct way is to create an interface for the Activity that the Fragment uses. See the docs here:
http://developer.android.com/training/basics/fragments/communicating.html
The other option, which decouples the Fragment from the Activity (which some may see as an advantage) is to use an Intent. With that approach, you need to look into the onNewIntent method, as it is not obvious exactly how it works.
Either one should be fine, especially since you are exploring ideas at this point.
What I have is a canvas that takes up nearly all of the screen, then under that I want a row of buttons and some other widgets. So I did this.
XML Code
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:id="#+id/myLayout"
android:orientation="vertical"
android:layout_height="match_parent" >
<com.zone.manager.Tab3
android:id="#+id/tab3_display"
android:layout_width="fill_parent"
android:layout_height="620dp" />
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="match_parent" >
<Button
android:id="#+id/addZone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add Zone" />
<Button
android:id="#+id/helpZone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Help" />
<SeekBar
android:id="#+id/seekBar1"
android:paddingTop="9dp"
android:layout_width="179dp"
android:layout_height="wrap_content" />
</LinearLayout>
Java Code
public class Tab3 extends View implements OnTouchListener, OnClickListener {
public Tab3(Context context, AttributeSet attrs) {
View parent = (View) getParent();
addZone = (Button) parent.findViewById(R.id.addZone);
addZone.setOnClickListener(this);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
. . . draws a bunch of stuff
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.addZone:
String w = "W~20~0~0~0~0~0";
Log.d("ZoneSize", "Zone set");
MyApplication.preferences.edit().putString( "ZoneSize", w ).commit();
MyApplication.preferences.edit().putBoolean("ZoneSizeReady", true).commit();
break;
}
}
However my problem with this is that I believe the code is not reconising where the addZone is. Because when I have the addZone.setOnClickListener active my program will crash, but when I don't have it active the layout looks like how I want it. What must I do to fix this?
addZone = (Button) findViewById(R.id.addZone);
addZone will be null because com.zone.manager.Tab3 does not have any children
So it is obvious that your code will crash
So either you will give com.zone.manager.Tab children which require also to change the base class from View to ViewGroup,
or you start with com.zone.manager.Tab parent. Something like
View parent = (View) getParent ();
addZone = (Button) parent.findViewById(R.id.addZone);
i have some tips which will make you avoid such weird bugs and others:
the code of the custom view relies on an xml layout that uses the custom view .
this is bad coding.
instead, you should use LayoutInflater , use a layout xml file for the custom view for it , and then do the "findViewById" and add the clickListeners to any view inside that you wish.
i think it's also wrong to set the custom view to hold the click listener of the other views without checking which of them was clicked . either add a check , or add a different listener for each of them (which i personally prefer) .