Using ViewPager2 to step-by-step SignUp form with Fragments - java

I'm trying to implement a SignUp form with viewpager2 where the user is asked to input its name, password, phone number and photo in a 4-step sequential prompt. So I have an activity that contains a ViewPager2, 4 different fragments and 4 different classes - one for each prompt.
Each layout has an EditText for the input and a "Next" Button for the submit and going to the next item on viewpager. For each fragment the input is validated at typing and its "Next" button becomes green and clickable when validated (ex: phone has more than 6 characters). This can be seen in the example-code I show below. (Please understand that I removed some code in order to be more clear)
example-layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/et_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:lines="1" />
</com.google.android.material.textfield.TextInputLayout>
<Button
android:id="#+id/bt_next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="next" />
</LinearLayout>
</LinearLayout>
example-fragment-class.java: (example of password, but name, phone, are very similar)
public class PasswordFragment extends Fragment implements APIConnectionCallback {
private FragmentPasswordBinding passwordBinding;
private final AuthActivity parent;
private boolean isValidInput = false;
public PasswordFragment(AuthenticationActivity parent) {
this.parent = parent;
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater,
#Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
return FragmentPasswordBinding.inflate(inflater, container, false).getRoot();
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// saves password in shared preferences (to capture it at the last viewpager item and submit) and changes viewpager to the next item
passwordBinding.btNext.setOnClickListener(view -> {
SharedPreferences sharedPreferences = parent.getSharedPreferences(AuthenticationActivity.AUTHENTICATION_CREDENTIALS, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("password", Objects.requireNonNull(passwordBinding.etPassword.getText()).toString());
editor.apply();
parent.getViewPager().setCurrentItem(parent.getViewPager().getCurrentItem() + 1, true);});
}
#Override
public void onStart() {
super.onStart();
passwordBinding.btNext.setOnClickListener(view -> {
if(isValidInput) {
// queries the server if submit is clicked and input is valid
}
});
// validates input while typing
passwordBinding.etPassword.addTextChangedListener(
new Validator.TextValidator(passwordBinding.etLoginPassword) {
#Override
public void validate(TextView textView, String password) {
isValidInput = Validator.matches(password, Validator.VALIDATION_KEY.PASSWORD);
submitButtonStateChange(); // changes the "clickability" of the submit button
}
}
);
}
private void submitButtonStateChange() { // this is repeating code for all fragments
passwordBinding.btNext.setBackgroundTintList(getActivity().getBaseContext().getColorStateList(
isValidInput ? R.color.green : R.color.black
));
}
}
My code is working but feels like a mess and too repetitive. For each Fragment class the button behaviour is very similar (only changes the type of validation). There must be a 'smarter way' of doing this without all the repeating code and all the different 4 classes + 4 layouts. Thought of using an abstract Fragment that generalizes some of the repeating code for the Fragment classes, but still it doesn't solve the necessity of having all those classes and layouts.
I could imagine doing this with a single Fragment class that changes implementation of its methods according to its position within the viewpager, but can't materialise this into a working code.
Is there any good idea or practice in order to tackle something like this?

Related

Scroll from bottom to top does not work using SwipeRefreshLayout

I have implemented SwipeRefreshLayout and it works fine basically. https://developer.android.com/training/swipe/add-swipe-interface.html
I am facing weired issue when you go to the bottom of the list and when you try to scroll to top the SwipeRefreshLayout refreshes.
That is not what I need. I need just scroll to the top of the List and not refresh the ListView.
I mean it should be some condition when to refresh depending where we stand. Right? Because the expecting behavior is allow refresh when we at the top of the ListView.
Please help.
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swiperefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:orientation="vertical"
>
<SearchView
android:id="#+id/editSearch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:iconifiedByDefault="false"
android:queryHint="Input the number"
/>
<ListView
android:paddingTop="5dp"
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</android.support.v4.widget.SwipeRefreshLayout>
And the code
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_fragment_two, container, false);
swiperefresh = (SwipeRefreshLayout) view.findViewById(R.id.swiperefresh);
swiperefresh.setColorScheme(R.color.colorPrimary, R.color.colorAccent, R.color.colorPrimaryDark, R.color.colorPrimary);
swiperefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
swiperefresh.setRefreshing(true);
Log.d("Swipe", "Refreshing Number");
// Get data from WebAPI or database cache
}
});
return view;
}
Well... Finally I found solution here Scroll up does not work with SwipeRefreshLayout in Listview
So my layout is not gonna be changed but the code yes.
We have to do following
Implement AbsListView.OnScrollListener like public
class FragmentTwo extends ListFragment implements SearchView.OnQueryTextListener, AbsListView.OnScrollListener
Add two methods of the implemented interface AbsListView.OnScrollListener
like here
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
swiperefresh.setEnabled(firstVisibleItem == 0);
}
And the key here is
swiperefresh.setEnabled(firstVisibleItem == 0);
implements OnScrollListener inside listFragment
this library allows you to choose between pull-up and pull-down :
https://github.com/chrisbanes/Android-PullToRefresh
Pull Up to Refresh
By default this library is set to Pull Down to Refresh, but if you want to allow Pulling Up to Refresh then you can do so. You can even set the View to enable both Pulling Up and Pulling Down using the 'both' setting. See the Customisation page for more information on how to set this.
I don't think the SwipeRefreshLayout does allow that.

Using BottomBar prevents fragments from opening?

I am using the Support Library to add a bottom bar similar to the material design one. The bottom bar works great but it seems that if I have the bar displayed, if I try to open any fragment from my custom adapter, the fragment does not open...or maybe it opens behind my main layout? I have no idea how to figure this out. Below is my code.
I've read more posts on SO and around the web and I think this is related to the fragment being properly loaded but below or next to the bottom bar...and that is why it isn't visible? Why does this happen? Is it because the bottom bar has a LinearLayout? I defined it as a menu so I'm not sure if I can control it being a LinearLayout....
Setting up the bottom bar, this method is called from the onCreate of my activity:
public void setupBottomToolbar(Bundle savedInstanceState) {
mBottomBar = BottomBar.attach(MainActivity.this, savedInstanceState);
mBottomBar.setItems(R.menu.bottombar_menu);
mBottomBar.setOnMenuTabClickListener(new OnMenuTabClickListener() {
#Override
public void onMenuTabSelected(#IdRes int menuItemId) {
if (menuItemId == R.id.toolbar_jobs) {
} else if (menuItemId == R.id.toolbar_messages) {
} else if (menuItemId == R.id.toolbar_recentJobs) {
} else if (menuItemId == R.id.toolbar_employerPools) {
}
}
#Override
public void onMenuTabReSelected(#IdRes int menuItemId) {
if (menuItemId == R.id.toolbar_jobs) {
// The user reselected item number one, scroll your content to top.
} else if (menuItemId == R.id.toolbar_messages) {
} else if (menuItemId == R.id.toolbar_employerPools) {
} else if (menuItemId == R.id.toolbar_recentJobs) {
}
}
});
// Setting colors for different tabs when there's more than three of them.
// You can set colors for tabs in three different ways as shown below.
mBottomBar.getBar().setBackgroundColor(getResources().getColor(R.color.laborswipe_darkgray));
mBottomBar.setActiveTabColor(getResources().getColor(R.color.laborswipe_lightgray));
// Make a Badge for the second tab, with red background color and a value of "13".
BottomBarBadge unreadMessages = mBottomBar.makeBadgeForTabAt(1, getResources().getColor(R.color.laborswipe_orange), 5);
// Control the badge's visibility
unreadMessages.show();
//unreadMessages.hide();
// Change the displayed count for this badge.
//unreadMessages.setCount(4);
// Change the show / hide animation duration.
unreadMessages.setAnimationDuration(200);
// If you want the badge be shown always after unselecting the tab that contains it.
unreadMessages.setAutoShowAfterUnSelection(true);
// If you don't want this badge to be hidden after selecting the tab contains it.
unreadMessages.setAutoShowAfterUnSelection(false);
}
In my adapter, I am trying to open the fragment when you click a button, like this:
holder.desc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context, "Open Description", Toast.LENGTH_SHORT).show();
JobDescFragment firstFragment = new JobDescFragment();
((MainActivity)context).getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, firstFragment).commit();
}
});
If I comment out the call to setupBottomToolbar() in my onCreate of the activity, the fragment opens up fine...but that means I don't have the bottom bar...
What am I missing? There has to be a way to use the bottom bar and also open a fragment?
Thanks!
EDIT:
Here is the top part of my activity.
public class MainActivity extends AppCompatActivity {
private ArrayList<String> swipecardsList;
private ArrayList<Job> jobList = new ArrayList<Job>();
private JobAdapter arrayAdapter; //arrayadapter
private BottomBar mBottomBar;
SharedPreferences settings;
#InjectView(R.id.frame) SwipeFlingAdapterView flingContainer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Remove title bar
//this.requestWindowFeature(Window.FEATURE_NO_TITLE);
//color the notification bar with our company colors
Window window = this.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.setStatusBarColor(this.getResources().getColor(R.color.laborswipe_notificationbar));
//remove title from action bar and add the logo to the top left of the action bar
setupTopToolbar();
setContentView(R.layout.activity_main);
ButterKnife.inject(this);
//set up the bottom toolbar using the roughike library to mimic android material design
setupBottomToolbar(savedInstanceState);
My adapter:
public class JobAdapter extends ArrayAdapter<Job> {
private final Context context;
private final ArrayList<Job> jobs;
private final int layoutResourceId;
private final SwipeFlingAdapterView flingContainer;
private boolean isExpanded = false;
public JobAdapter(Context context, int layoutResourceId, ArrayList<Job> jobs, SwipeFlingAdapterView flingContainer) {
super(context, layoutResourceId, jobs);
this.context = context;
this.jobs = jobs;
this.layoutResourceId = layoutResourceId;
this.flingContainer = flingContainer;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
final ViewHolder holder;
String pay, hrs;
final Bundle fragmentParams = new Bundle();
LayoutInflater inflater = LayoutInflater.from(context);
if (view == null) {
view = inflater.inflate(layoutResourceId, parent, false);
holder = new ViewHolder();
holder.title = (TextView)view.findViewById(R.id.tv_jobTitle);
holder.desc = (TextView) view.findViewById(R.id.tv_JobDesc);
view.setTag(holder);
} else {
holder = (ViewHolder)view.getTag();
}
Job j = jobs.get(position);
holder.title.setText(j.getJobTitle());
holder.desc.setText(j.getDescription());
//when user clicks apply, swipe the card right
holder.apply.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Open up a fragment to display the entire job description
Toast.makeText(context, "Applied", Toast.LENGTH_SHORT).show();
flingContainer.getTopCardListener().selectRight();
}
});
//when user clicks dismiss, swipe the card left
holder.dismiss.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Open up a fragment to display the entire job description
Toast.makeText(context, "Dismissed", Toast.LENGTH_SHORT).show();
flingContainer.getTopCardListener().selectLeft();
}
});
//on click event listener for the job description field - open larger window to read description
holder.desc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Toast.makeText(context, "Open Description", Toast.LENGTH_SHORT).show();
JobDescFragment firstFragment = new JobDescFragment();
Fragment frag = new Fragment();
frag = firstFragment.newJobDescFrag(j.getDescription());
((MainActivity) context).getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, frag)
.addToBackStack("JobDesc").commit();
}
});
return view;
}
public class ViewHolder
{
TextView title;
TextView payrate;
TextView dateRange;
TextView workinghrs;
TextView location;
TextView companyname;
TextView desc;
TextView experience;
TextView equipment;
Button apply, dismiss, expand;
}
}
activity_main.xml:
<merge
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">
<com.lorentzos.flingswipe.SwipeFlingAdapterView
android:id="#+id/frame"
android:background="#color/laborswipe_lightgray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:context=".MainActivity"
android:layout_gravity="top" />
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</merge>
Fragment Layout:
<FrameLayout 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"
tools:context=".JobDescFragment">
<LinearLayout
android:id="#+id/outerDescriptionLayout"
android:layout_width="match_parent"
android:layout_height="400dp"
android:layout_gravity="center_horizontal|top"
android:orientation="vertical"
android:background="#drawable/swipecard_shadow"
android:gravity="top"
android:layout_marginLeft="5dp">
<LinearLayout
android:id="#+id/DescriptionLayout"
android:layout_width="match_parent"
android:layout_height="400dp"
android:layout_gravity="center_horizontal|top"
android:orientation="vertical"
android:weightSum="1"
android:gravity="top"
android:layout_marginTop="20dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="#00FF00"
android:clickable="true">
<TextView
android:layout_width="200dp"
android:layout_height="200dp"
android:text="Detailed Description:"
android:textColor="#000000"
android:id="#+id/tv_title" />
<TextView
android:layout_width="200dp"
android:layout_height="200dp"
android:text="THIS IS THE FULL DESCRIPTION"
android:textColor="#000000"
android:id="#+id/tv_fullDescription" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
Logcat:
08-07 11:20:47.799 13896-13896/com.lorentzos.swipecards.example I/System.out: DEBUG: job desc fragment loaded!
08-07 11:20:47.855 13896-13941/com.lorentzos.swipecards.example W/EGL_emulation: eglSurfaceAttrib not implemented
08-07 11:20:47.855 13896-13941/com.lorentzos.swipecards.example W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xaaa7f880, error=EGL_SUCCESS
08-07 11:20:48.002 13896-13941/com.lorentzos.swipecards.example V/RenderScript: 0xa1408000 Launching thread(s), CPUs 2
08-07 11:20:49.798 13896-13941/com.lorentzos.swipecards.example E/Surface: getSlotFromBufferLocked: unknown buffer: 0xae433ca0
When I use the bottom bar (not working- no fragment opened but toast displayed):
When I don't use the bottom bar (workin-fragment opened, background is green):
try to link a pic of problem and without problem(no bottombar) and since you are using merge the layout hierarchy will be laid off according to your activity's viewgroup(linear,relative) constraints(we don't know what they are like).
as you said when there is no bottombar ,you fragment displays perfectly though when the bottombar it there ,problem stats ,as per your log in fragment indicating that your fragment is loading perfectly even though when bottombar is visible mean fragment is there but is not visible ,seems like your fragment didn't get the appropriate space to get displayed.
other solution can be adding bottom bar to your fragment instead of activity to avoid any overlapping ,like
mBottomBar.attach(findViewById(R.id.fragmentContainer), savedInstanceState);
OK, I think the solution for this should be simple, from what I can see in your code, you are attaching the BottomBar to your activity, I think this is the problem. If you were to read the readme.md in the roughike/BottomBar github page you'd find this
Why is it overlapping my Navigation Drawer?
All you need to do is instead of attaching the BottomBar to your Activity, attach it to the view that has your content. For example, if your fragments are in a ViewGroup that has the id fragmentContainer, you would do something like this:
mBottomBar.attach(findViewById(R.id.fragmentContainer), savedInstanceState);
So, since navigation drawer works with transition a fragment in and out of view with animation, the same thing is happening when you are adding a new fragment to your activity.
The Solution
From what I can see in your code, your fragment container id is this: fragment_container in your activity layout. So according to the documentation you'd just need to do attach your bottomBar to the fragment_container instead of MainActivity.this
mBottomBar.attach(findViewById(R.id.fragment_container), savedInstanceState);
If the above doesn't work try this
What you'd need to do is add an extra FrameLayout to hold your bottombar, which has a transparent background, but is on top of your fragment.
So change your main_activity layout to
<merge
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">
<com.lorentzos.flingswipe.SwipeFlingAdapterView
android:id="#+id/frame"
android:background="#color/laborswipe_lightgray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:context=".MainActivity"
android:layout_gravity="top" />
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<FrameLayout
android:id="#+id/holder_bottombar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"/>
</merge>
Now in the code instead of attaching the bottom bar to mainactivity, just attach it to the holder like so
mBottomBar.attach(findViewById(R.id.holder_bottombar), savedInstanceState);

fragment button

I try to make a button active fragment, leading to a new layout with the url of this fragment. But it is not working. Something wrong. Please help
no receive error, but the button does not work.
code fragment
public class ContentFragment extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.content_fragment, container, false);
final View button = view.findViewById(R.id.bSendUrl);
button.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
EditText simpleEditText = (EditText) getView().findViewById(R.id.bTextUrl);
String strValue = simpleEditText.getText().toString();
Intent intent = new Intent(getActivity(), MainActivity.class);
intent.putExtra("url", strValue);
startActivity(intent);
}
}
);
return view;
}
}
xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TextInputLayout
android:id="#+id/input_TEXT_Url"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_below="#+id/include"
android:layout_alignParentEnd="true"
android:layout_alignParentStart="true"
android:layout_marginTop="6dp">
<EditText
android:id="#+id/bTextUrl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textUri"
android:hint="#string/url_edit_text" />
</android.support.design.widget.TextInputLayout>
<Button
android:layout_width="#dimen/latimea_button_send_tv"
android:layout_height="#dimen/inaltimea_button_send_tv"
android:text="#string/button_send_android_tv"
android:id="#+id/bSendUrl"
style="?android:attr/borderlessButtonStyle"
android:layout_below="#+id/input_TEXT_Url"
android:paddingLeft="16dp"
android:layout_marginLeft="16dp" />
</RelativeLayout>
Edit
I am removed openjdk and installed clean javasdk and is work fine
You are trying to find a reference to a Button before the fragment's view hierarchy is inflated. The fragment transaction you're using does not immediately create the view hierarchy after commit() is called. This means the view with id bTextUrl is not yet created and findViewById() returns null.
Also, it's kind of strange for an activity to be messing with the views of child fragments. I recommend that you modify the views of the fragment within the fragment itself (not within the containing activity like you're doing now).

How to create a terminal/console

i wanted to create a terminal/console, where the user can enter commands. I know java, but i'm new to xml, so i wanted to know how i can spawn text under text and if it gets to long it should be scrollable, here's a picture:
and here's my xml cpde for it:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#d1d1d1">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1">
<EditText
android:layout_width="175dp"
android:layout_height="wrap_content"
android:id="#+id/consoleText"
android:layout_gravity="bottom"
android:hint="Command"
android:layout_weight="0.99" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send"
android:id="#+id/sendButton"
android:layout_gravity="bottom" />
</LinearLayout>
</LinearLayout>
and here's my code for getting the text:
public class FragmentConsole extends Fragment{
EditText text;
Button button;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.console,
container, false);
button = (Button) view.findViewById(R.id.sendButton);
text = (EditText)view.findViewById(R.id.consoleText);
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Log.v("EditText", text.getText().toString());
}
});
return view;
}
}
So i will use some photoshopped pictures to show what i want to do, so each time i enter a command in this case i will use the example "command one","command two" & "command three", so and if i click the send button after each of them they should apper like this:
so and if the text reaches this black bar:
the above added text should get pushed in a scrollview and every new text will also get part of the scrollview, so that you can scroll through your commands later on.
I know this is a long post and i hope it is clear what i want to do and someone will know how i could do this. So thanks in advance :)
For this task you should consider using ListView and add every command as new row in this view. It'll also take care for scrolling and you'r text wont colide with your EditText.

Null Pointer Exception Android

I am trying to make a button, count clicks and display them in a text view.
Tried everything i knew.
XML:
<LinearLayout
android:id="#+id/gpulay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="20dp" >
<TextView
android:id="#+id/master_control_text_gpulay"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Master Control :"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="#+id/plus_gpulay"
android:layout_width="35dp"
android:layout_height="35dip"/>
</LinearLayout>
Here is my code:
public class Main extends Fragment {
int c=0;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (container == null) {
return null;
}
ListView GPU_LAYOUT = (ListView)inflater.inflate(R.layout.gpu, container, false);
TextView text = (TextView) GPU_LAYOUT.findViewById(R.id.text1);
Button plus = (Button) GPU_LAYOUT.findViewById(R.id.butt1);
plus.setOnClickListener(new OnClickListener() { //null pointer this line, but it's from .srtText i think
public void onClick(View v) {
c++;
text.setText(c);
}
});
}
return GPU_LAYOUT;
}
App force closes when i open it, so i don't even see the main layout.
The NPE is coming from here
text.setText(c);
you are using the wrong setText() method. When you place an int in there it looks for a resource with that id. You need to give it a String. You can do this several ways. One way is to change it to
text.setText("" + c);
You could also do
text.setText(String.valueOf(c));
TextView Docs notice the different methods.
Its just wrong to create your app in onCreateView while working in an Activity.
You can still do all this in your onCreate Method.
My Guess would be that GPU_Layout is null or doesnt contain your button. Thats why button (plus) is Null and calling setOnClickListener on it throws a NullPointerException.
Also it would help if you could explain WHEN the error Occurs, during inflating/building the Activity or during actually pressing the Button
1) You need to extend your class from Fragment instead of Activity. Then your method onCreateView will work. Then set this fragment as contentView of your Activity.
2) You can't set int as text of textView or any other widget. You need to convert it into String first using String.valueOf(count);

Categories