I currently have code that should make the LinearLayout toggle between being VISIBLE and GONE, but it only toggles if it is visible, and does not toggle if the Layout is Gone. Could someone explain what i have done wrong?
XML:
<ImageButton
android:id="#+id/info_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#drawable/myimage"
android:onClick="toggleInfo"/>
<LinearLayout
android:id = "#+id/text_box"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"
android:gravity="center">
<TextView
android:id="#+id/info_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="#string/test"
android:textSize="18sp"
android:textStyle="normal"
android:background="#color/white"
/>
</LinearLayout>
JAVA:
public void toggleInfo(View view) {
LinearLayout infoText = findViewById(R.id.text_box);
if (infoText.getVisibility() == LinearLayout.GONE) {
infoText.setVisibility(LinearLayout.VISIBLE);
}
if (infoText.getVisibility() == LinearLayout.VISIBLE) {
infoText.setVisibility(LinearLayout.GONE);
}
}
By default your layout is visible. And when you are calling the method, it checks if the view is visible. The second if condition satisfies with it. So first time the LinearLayout.GONE is getting called.
But when you are clicking second time (now your view is not visible), the first condition satisfies and LinearLayout.VISIBLE is getting called. Now your view is visible. So the second condition also satisfies, and the LinearLayout.GONE is getting called again.
Just put and else and it will work.
public void toggleInfo(View view) {
LinearLayout infoText = findViewById(R.id.text_box);
if (infoText.getVisibility() == LinearLayout.GONE) {
infoText.setVisibility(LinearLayout.VISIBLE);
}else if (infoText.getVisibility() == LinearLayout.VISIBLE) {
infoText.setVisibility(LinearLayout.GONE);
}
}
Just do this:
public void toggleInfo(View view) {
LinearLayout infoText = findViewById(R.id.text_box);
infoText.setVisibility(infoText.getVisibility() == LinearLayout.GONE ? LinearLayout.VISIBLE : LinearLayout.GONE);
}
Rupam absolutely right. Another way to fix is - to add return to your first condition
also avoid using LinearLayout.GONE
better use View.GONE instead(if something will change - for example you will decide to use RelativeLayout instead of current LinearLayout... well... you got me I think)
if (infoText.getVisibility() == LinearLayout.GONE) {
infoText.setVisibility(LinearLayout.VISIBLE);
return;
}
if (infoText.getVisibility() == LinearLayout.VISIBLE) {
infoText.setVisibility(LinearLayout.GONE);
}
Related
I have an EditText inside of a ScrollView which is pre-filled with a dynamic amount of text. It could be one line or 50 or more. At this point, the EditText is uneditable and the text is shown just fine. However, when I press a button to make the edit text editable, the entire contents of the EditText are thrown into one very long, horizontally scrolling line.
You can see exactly what I'm talking about here:
https://zippy.gfycat.com/GenerousBigHerring.webm
How can I prevent this from happening? I've been screwing around with this for a while now. I've tried setting lines and maxLines, etc, but I can't figure it out.
Edit:
This is my current ScrollView/EditText:
<ScrollView
android:id="#+id/result_text_scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/result_title_text"
android:layout_above="#+id/result_bottom_sheet"
android:layout_marginTop="20dp"
android:padding="5dp">
<EditText
android:id="#+id/extracted_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:padding="15dp"
tools:text="Hello, World"
android:textColor="#color/black"
android:textStyle="bold"
android:textSize="#dimen/extracted_text_size"
android:textIsSelectable="true"
android:inputType="none"
/>
</ScrollView>
From code, here's what I'm doing to to enable/disable editing:
#Override
public void enableTextEditing() {
mExtractedText.setInputType(InputType.TYPE_TEXT_FLAG_MULTI_LINE);
mExtractedText.setOnKeyListener(this);
}
#Override
public void disableTextEditing() {
mExtractedText.setInputType(InputType.TYPE_NULL);
mExtractedText.setOnKeyListener(null);
}
#Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
if (keyEvent.getAction() == KeyEvent.ACTION_DOWN && keyEvent.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
//All this does is call the View methods to disable text editing
//and close the keyboard.
mPresenter.doneEditingButtonPressed();
return true;
}
return false;
}
Add android:lines , android:minLines and android:maxLines to your EditText view
Also change android: inputType = "textMultiline"
You can add android:scrollbars="vertical" to your EditText as well if you wish
I'm trying to stop the progress of the seek bar unless the user started below progress(10), this ensures the user actually has to slide it, thus avoiding accidental activation. I've tried this so far and it looks like it'd work, however the slide bar can still be moved from anywhere (progress(0) up to progress(100).
sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
private Boolean isInRange = true;
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
if (seekBar.getProgress() > 95) {
((MainActivity)getActivity()).currentOrder = null;
((MainActivity)getActivity()).showMain();
} else {
seekBar.setProgress(0);
isInRange = false;
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
if (seekBar.getProgress() < 10) {
isInRange = true;
} else {
seekBar.setProgress(0);
isInRange = false;
}
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(!isInRange) {
seekBar.setProgress(0);
}
}
});// Set on seek bar change listener
just in case you need it, here's the XML code of the seekbars container:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorFocus"
android:layout_alignParentBottom="true"
android:orientation="vertical">
<LinearLayout
android:id="#+id/seperator_bottom"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#android:color/darker_gray"
android:orientation="horizontal" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/btn_delivery_disabled"
android:padding="16dp"
android:layout_margin="16dp">
<SeekBar
android:id="#+id/seek"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:max="100"
android:progressDrawable="#android:color/transparent"
android:thumb="#mipmap/ic_slide" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/delivered"
android:textAppearance="#android:style/TextAppearance.DeviceDefault.Large"
android:gravity="center"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentStart="true"
android:id="#+id/textView" />
</RelativeLayout>
</LinearLayout>
The setProgress is absolute value, not relative to where your progress currently is. What you actually are doing is essentially resetting the progress to 0 any time when the touch is not within the first 10 percent of the SeekBar, not within 10 percent of where the progress is. That, of course, is assuming that you can not provided max attribute, in which case the max value is set at 100.
So, you need to adjust your code to read current value, then compare it to current and see if it is within 10 percent. I would also recommend to keep track of starting position and end position rather then only having a simple boolean value to track it. Then you have to evaluate the value in relation to current position.
I was wondering if there is a way to group EditText in a way that you can only traverse among a group of them.
The problem is that I rely on reaching the end of the first group and use EditorInfo.IME_ACTION_DONE in order to trigger a certain action.
The inner group of EditTexts is inside a LinearLayout.
Put the text boxes in a layout(linear or relative) only those EditText which you want to make a group. layout will act as group. Add this on your every Edittext xml--
android:maxLines="1"
if it does not works the you can handle focus.
Focus Handling
Focus movement is based on an algorithm which finds the nearest neighbor in a given direction. In rare cases, the default algorithm may not match the intended behavior of the developer.
Change default behaviour of directional navigation by using following XML attributes:
android:nextFocusDown="#+id/.."
android:nextFocusLeft="#+id/.."
android:nextFocusRight="#+id/.."
android:nextFocusUp="#+id/.."
Besides directional navigation you can use tab navigation. For this you need to use
android:nextFocusForward="#+id/.."
To get a particular view to take focus, call
view.requestFocus()
To listen to certain changing focus events use a View.OnFocusChangeListener
Keyboard button
You can use android:imeOptions for handling that extra button on your keyboard.
Additional features you can enable in an IME associated with an editor to improve the integration with your application. The constants here correspond to those defined by imeOptions.
The constants of imeOptions includes a variety of actions and flags, see the link above for their values.
Value example
ActionNext :
the action key performs a "next" operation, taking the user to the next field that will accept text.
ActionDone :
the action key performs a "done" operation, typically meaning there is nothing more to input and the IME will be closed.
Code example:
<RelativeLayout 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=".MainActivity" >
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="32dp"
android:layout_marginTop="16dp"
android:imeOptions="actionNext"
android:singleLine="true"
android:ems="10" >
<requestFocus />
</EditText>
<EditText
android:id="#+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/editText1"
android:layout_below="#+id/editText1"
android:layout_marginTop="24dp"
android:imeOptions="actionDone"
android:singleLine="true"
android:ems="10" />
</RelativeLayout>
If you want to listen to imeoptions events use a TextView.OnEditorActionListener.
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
performSearch();
return true;
}
return false;
}
});
Edit:
For dynamic edittext you can try..
EditText etCurrent;
Set an OnTouchlistener on each EditText:
valueET.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (etCurrent != null) {
if (etCurrent.getId() != v.getId()) {
if (!check(etCurrent.getId())) {
etCurrent.setSelection(0,
etCurrent.getText().toString().length());
return true;
} else {
etCurrent = (EditText) v;
}
}
} else {
etCurrent = (EditText) v;
}
}
return false;
}
});
How to recover the problem of Null pointer exception in the place of menu.setOnClickListener(new View.OnClickListener() {
,
i have an imageview(menu) if i press on that another activity(about page) should get opened, but here on OnClick of imageview, i'm getting above error and app gets force close.
Here's the code
public class About extends Activity {
LinearLayout line1, line2;
ImageView menu;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_about);
menu = (ImageView)findViewById(R.id.menu);
menu.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
menu.setVisibility(View.VISIBLE);
// TODO Auto-generated method stub
line1.setVisibility(View.VISIBLE);
if (line2.getVisibility() == View.INVISIBLE || line2.getVisibility() == View.GONE) {
line2.setVisibility(View.VISIBLE); }
else {
line2.setVisibility(View.INVISIBLE);
}
}
});
ImageView about = (ImageView) findViewById(R.id.about);
about.setOnClickListener(new View.OnClickListener() {
public void onClick(View v){
startActivity(new Intent(About.this, About.class));
}
});
xml file
<RelativeLayout 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:background="#color/black" >
<LinearLayout
android:id="#+id/ll1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/black"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true">
<ImageView
android:id="#+id/menu"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="#drawable/menu" />
</LinearLayout>
<LinearLayout
android:id="#+id/ll2"
android:layout_width="199dp"
android:layout_height="wrap_content"
android:background="#color/black"
android:layout_toRightOf="#+id/ll1"
android:visibility="gone"
>
<ImageView
android:id="#+id/about"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_above="#+id/textView1"
android:layout_toLeftOf="#+id/jobs"
android:src="#drawable/about" />
</LinearLayout>
<TextView
android:id="#+id/textView3"
android:layout_width="match_parent"
android:layout_height="50dip"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="#color/white"
android:textColor="#color/white"/>
you are getting NullPointerException because you didn't have initialize imageview.please do it first.
ImageView menu=(ImageView)findViewById(R.id.menu);
write this line before you set onClick Listener to your image view and you are done.hope it will help.
As I suspected, you have declared menu as an instance variable (at the top of your class), but you never instantiate it as a local variable. Add the line
menu = (ImageView)findViewById(R.id.menu)
at the top of your onCreate() method, BEFORE you set the OnClickListener, and it will work.
There is a difference between declaring the instance variable (which you have done) and actually initializing it. In this sense, you can look at the onCreate() method like a constructor in a regular java class. It's not enough to declare the variable at the top of the class, you have to initialize it as a variable of the actual object.
This might sound trivial, but believe me it's not. When I was first learning java, before I wrapped my head around this concept, I spent many hours screaming at the screen over the same sorts of errors you're having now.
You've not properly initialized the menu variable before setting listener you should
menu = (ImageView)findViewById(id.menu);
then write your listen line....
You should pass the context of the activity which is running not the activity that you desire to run,the Problem is About.this , Replace it with the context of current Activity
startActivity(new Intent(About.this, About.class));
you have not Instantiate menu 1st instantiate.
You are calling the same class with in the same activity change your following code as following
startActivity(new Intent(About.this, About.class));
to
startActivity(new Intent(getApplicationContext(), NewClass.class));
or
startActivity(new Intent(CurrentClass.this, NewClass.class));
I had a similar issue. I found the xml id I'd used in findViewById() came from a different page layout than the one active at the time.
No warnings. Just need to make sure common buttons like Save have a good naming convention.
I have been playing around a lot with the ExpandableListView and I cannot figure out where to add the button listeners for the button that will be the children in the view. I did manage to get a button listener working that uses getChildView() below, but it seems to be the same listener for all the buttons.
The best case scenario is that I would be able to implement the button listeners in the class that instantiates the ExpandableListAdapter class, and not have to put the listeners in the actual ExpandableListAdapter class. At this point I don't even know if that is possible
I have been experimenting with this tutorial/code: HERE
getChildView()
#Override
public View getChildView(int set_new, int child_position, boolean view, View view1, ViewGroup view_group1)
{
ChildHolder childHolder;
if (view1 == null)
{
view1 = LayoutInflater.from(info_context).inflate(R.layout.list_group_item_lv, null);
childHolder = new ChildHolder();
childHolder.section_btn = (Button)view1.findViewById(R.id.item_title);
view1.setTag(childHolder);
childHolder.section_btn.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
Toast.makeText(info_context, "button pushed", Toast.LENGTH_SHORT).show();
}
});
}else {
childHolder = (ChildHolder) view1.getTag();
}
childHolder.section_btn.setText(children_collection.get(set_new).GroupItemCollection.get(child_position).section);
Typeface tf = Typeface.createFromAsset(info_context.getAssets(), "fonts/AGENCYR.TTF");
childHolder.section_btn.setTypeface(tf);
return view1;
}
Any help would be much appreciated. Thank you and I will be standing by.
If the buttons are in the ExpandableListView, their listener needs to be in the adapter.
I'm not sure the thrust of your question, but if you are asking how do you relate the button to the contents of the child row, I can answer that. :p
I'll assume a somewhat simple child row layout for demonstration purposes.
child_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal" >
<TextView
android:id="#+id/ListItem1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left|center_vertical"
android:paddingLeft="7dip"
android:paddingRight="7dip"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/ListItem2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right|center_vertical"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:id="#+id/button"
android:focusable="false"
android:focusableInTouchMode="false"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
Then, to get the contents of the row when your button is pressed, you use the button to backtrack to the parent vieew and then get the necessary child views and their contents:
childHolder.section_btn.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
LinearLayout ll = (LinearLayout) v.getParent(); // get the view containing the button
TextView tv1 = (TextView) ll.findViewById(R.id.ListItem1); // get the reference to the first widget
TextView tv2 = (TextView) ll.findViewById(R.id.ListItem2); // get the reference to the second widget
String text1 = tv1.getText.toString(); // Get the contents of the first widget to a string
String text2 = tv2.getText.toString(); // Get the contents of the second widget to a string
}
});
If this isn't what you were looking for clarify your question and I'll take another shot at it.