i am trying to achieve a behavior where user click an arrow that can reveal more content such as more description abort something. It can a recycler view as well where more things can be added dynamically and the list will expand.Right now i do not have any idea how it can be achieved. I tried searching on the internet for solutions and saw a widget called spinner but i do not think it can help me achieve my desired behavior. YouTube does apply similar behavior as well
Below are the pictures which will make my question clear. Any help would be appreciated Thank You
Before clicking the arrow pic 1
After clicking the arrow pic 2
In your layout.xml include a nested layout that includes a Textview that holds the additional information and set android:visibility="gone". Use an OnClickListener to the button that is meant to expand the view. In the onClick method check if the view is visible or not. If it's not you make it visible, otherwise you set it to gone again.
layout:
...
<ImageView
android:id="#+id/chevron"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#android:drawable/chevron"
/>
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="your additional info here"
android:visibility="gone"/>
...
In your Activity:
ImageView yourView = findViewById(R.id.chevron);
..
yourView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (view.getVisibility() == View.Gone) {
view.setVisibility(View.Visible);
} else {
view.setVisibility(View.Gone);
}
}
});
I used for this purpose ExpandbleLayout from this github library
ExpandableLayout. In readMe of the github repo you can find example of using it, you can get similar experience with as in your example, without need to manually create View for arrow and handling the animation.
You can use it like this :
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.github.aakira.expandablelayout.ExpandableRelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:ael_expanded="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Some text goes here"
android:textSize="28sp" />
</com.github.aakira.expandablelayout.ExpandableRelativeLayout>
And in your java/kotlin code : do additional logic to expand/collapse call : expandableLayout.toggle();.
All the credit goes to the author of the library.
https://github.com/AAkira/ExpandableLayout
Related
i'm here to ask if anyone knows a workaround to the issue i'm failing to fix.
Basically i'm coding a simple Chat App in Android using Firebase as an exercise. I'm using a ListView in my main layout and a simple Layout to use for each "message bubble". Here comes the problem: when i visualize the messages that i retrieve from Firebase i change the color of the bubble based on the current user in runtime, when first loaded each bubble has the right color, but by scrolling up and down my messages more and more bubbles take on the "ActiveUser" color even if they belong to different users, any ideas? I'll leave the code i'm using down below
Main Layout ListView
<ListView
android:id="#+id/list_of_messages"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/inputArea"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:divider="#android:color/transparent"
android:dividerHeight="16dp"
android:paddingStart="15dp"
android:paddingBottom="5dp"
android:paddingEnd="15dp"
android:paddingTop="10dp"/>
Message Bubble Layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:id="#+id/message_bubble"
android:background="#drawable/normal_message_background">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:id="#+id/message_user"
android:textStyle="normal|bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="#id/message_user"
android:layout_marginStart="10dp"
android:id="#+id/message_time" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/message_user"
android:layout_alignParentStart="true"
android:layout_marginTop="5dp"
android:id="#+id/message_text"
android:textAppearance="#style/TextAppearance.AppCompat.Body1"
android:textSize="18sp" />
FirebaseListAdapter and runtime style change code chunk
private void displayChatMessages() {
ListView listOfMessages = findViewById(R.id.list_of_messages);
FirebaseListOptions<ChatMessage> options = new FirebaseListOptions.Builder<ChatMessage>().setLayout(R.layout.message)
.setQuery(dbMessagesReference, ChatMessage.class).build();
mAdapter = new FirebaseListAdapter<ChatMessage>(options) {
#Override
protected void populateView(View v, ChatMessage model, int position) {
// Get references to the views of message.xml
RelativeLayout messageBubble = v.findViewById(R.id.message_bubble);
TextView messageText = v.findViewById(R.id.message_text);
TextView messageUser = v.findViewById(R.id.message_user);
TextView messageTime = v.findViewById(R.id.message_time);
// Set their text
messageText.setText(model.getMessageText());
messageUser.setText(model.getMessageUser());
messageTime.setText(model.getMessageTime());
if (messageUser.getText().equals(FirebaseAuth.getInstance().getCurrentUser().getDisplayName()))
messageBubble.setBackgroundResource(R.drawable.active_user_message_background);
}
};
listOfMessages.setAdapter(mAdapter);
}
EDIT:
I've fixed the problem by declaring the else statement to set the normal drawable variant back if the usernames did not match, however once changed the background Resource in runtime the bubble looks smaller and doesn't wrap around all the text, does anyone know the reason of this?
2ND EDIT:
I've found the solution to my second problem in this other post: Where'd padding go, when setting background Drawable?
Apparently the issue should have been fixed back in API 19/21, however if you still experience that problem apply the workaround explained in the thread linked above
ListView will reuse views to help with performance. This means when we scroll the adapter will just place your content in a view that was slated to go off screen rather than inflating a new view. This is causing all views that you set the current user background on to always keep that background since you don't have a condition to set it back if the view is filled with non-current user data.
To fix this add the following condition:
if (messageUser.getText().equals(FirebaseAuth.getInstance().getCurrentUser().getDisplayName())){
messageBubble.setBackgroundResource(R.drawable.active_user_message_background);
}
else{
messageBubble.setBackgroundResource(R.drawable.normal_message_background);
}
Is it possible to add multiple TextView inside one ImageButton with colour background ?
The core need is to have a button with the action text on it, and a subtext nearby explaining the action or giving other information related to the action. This subtext can vary from time to time.
Considering this requirement, one solution is to have a normal button and a subtext below, not clickable. But I find it messy. A better approach which I like is, on iOS for instance, to have a clickable UIView containing the action as bold text and the explanation as light text. See the image bellow containing 4 buttons :
How to achieve the same on Android with Java ? The closest I can have is to have an ImageButton bellow a TextView, and it does not sound right.
Is possible to nest TextViews inside an ImageButton ? If not, what is the best alternative ?
I hope this may be useful it explains how to position a textView within and in front of a imageView in the XML.
TextView inside of ImageButton/ImageView XML - Android Dev
Obviously make sure each view has a unique id/name which you can assign as shown here on this link
Sorry I cannot explain specifically myself but it has been a while since developing in Java for Android.
I dont know why you want this behaviour but you can make a container for your views and add a click listener to the whole view. you can also use it anywhere.
an example of this would be.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container"
android:layout_width="match_parent"
android:background="#drawable/container_background"
android:layout_height="wrap_content">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="0.33"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="0.33"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="0.33"
/>
add a selector background
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="#color/text_pressed" />
<item android:color="#color/normal" />
</selector>
and the listener
findViewById(R.id.container).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
I am a beginner trying to make a calculator app in Android Studio that takes input from buttons. This is proving to be much more difficult than I thought it would be compared to just using EditText, but it has been a great learning experience so far.
I am working on the display portion of the app for which I am using a textView. I have it set up so that when a button is clicked, the button's value is appended to the textView. It's a calculator, so I want the textView to be displayed on a single line and shift horizontally for new input when the width of the textView is full.
I found a way to do this from another person's post that works by setting the following in the XML:
android:inputType="text"
android:maxLines="1"
When I did this it does exactly what I want, but I get an IDE warning that says:
Warning: Attribute android:inputType should not be used with <TextView>: Change element type to <EditText> ?
Without the android:inputType="text" piece of code, the textView doesn't seem to scroll properly and I don't want to use an EditText. Is this something to worry about? Is there a better way to do this?
Thanks for the help.
Do not use inputType in TextView.
From this link - https://youtu.be/HYt1Ntu89X4
What I understood is you want the text to scroll dynamically i.e. on Button press.
You can do it like this :
XML
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/hzw"
android:fillViewport="true"
android:layout_gravity="end">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tv1"
android:maxLines="1"
android:textSize="20dp"
android:textStyle="bold"
android:gravity="end"/>
</HorizontalScrollView>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/b"
android:text="Add Text"/>
Java
tv1 = (TextView)findViewById(R.id.tv1);
tv1.setText("123+123");
hzw = (HorizontalScrollView)findViewById(R.id.hzw);
b = (Button)findViewById(R.id.b);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
tv1.append("d+1+cff");
hzw.post(new Runnable() {
#Override
public void run() {
hzw.fullScroll(View.FOCUS_RIGHT);
}
});
}
});
I started learning java a few days ago, so I'm quite lost with it.
I want to show a text received from an intent and make it look like this:
"You've written : ."
It isn't working at all and I'm only able to show the text from the intent.
Here's my code:
// Create the text view
TextView textView = new TextView(this);
textView.setTextSize(40);
System.out.print("You've written: ");
textView.setText(message);
System.out.print(".");
// Set the text view as the activity layout
setContentView(textView);
}
Besides, I'm trying to display the text written above in the first line of the page (or as many lines it takes) and, below, a label to insert a text together with a Button. The problem is that I can only see the text from the intent.
Here's my code:
<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: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=".DisplayMessageActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
<EditText android:id="#+id/edit_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="#string/edit_message" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_send"
android:onClick="sendMessage"/>
</RelativeLayout>
Thankyou very much, I wish I'll be answered soon.
Instead of System.out.println.
Do like this.
<TextView
android:id="#+id/topTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
and Get the view in activity.
public void onCreate(Bundle bundle) {
.........
setContentView(layout_xml);
TextView textView = (TextView)findViewById(R.id.topTextView);
textView.setText("You've written: " + message + " .");
.........
}
If you are trying to reference the TextView inside your layout it needs to referenced in the Activity. The above solution shows you how to handle that. setContentView(R.layout.file_name) is what should be used to reference a layout created inside an xml file stored in res/layout/file_name.xml or created manually inside your code. If you are going to call setContentView for a layout contructed inside your (Activity) it will take some more code. If the message is all is need to be displayed you can always call Toast.maketText(Context, message, Toast.LENGTH_SHORT).show(); for example. The other suggestion is Java developers are used to using System.out.println() to debug to the console. In Android they have a neat feature we use called LogCat that can display messages going on inside your code by saying (example for debugging purposes)
Log.d(TAG, message); Where TAG is usually a constant defined for the Activity,Fragment, etc. you are in so you can see where the message is coming from and display whatever value you normally would have used in System.out.println().
I am building a view in my Android application using a sliding drawer widget. I have implemented my own custom handles (just a row of menu buttons which then changes the content of the drawer and then activates the openAmination). I have managed to disable the standard handle provided with the slidingdrawer but I want to completely remove it.
None of the standard visibility stuff in xml or java works in hiding/removing the handle:
<SlidingDrawer android:layout_width="fill_parent"
android:id="#+id/slidingDrawer1"
android:layout_height="fill_parent"
android:handle="#+id/handle"
android:content="#+id/content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:allowSingleTap="false"
>
<Button android:layout_width="wrap_content"
android:text="Close"
android:layout_height="wrap_content"
android:id="#+id/handle"
android:visibility="gone" //DOES NOT WORK
</Button>
<LinearLayout android:id="#+id/content"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FFFFFF">
</LinearLayout>
</SlidingDrawer>
I also tried importing the view in java and doing the same but also does not work.
View h = findViewById(R.id.handle);
h.setVisibility(View.GONE);
I have then tried extending the slidingDrawer class and making my own but it still requires a handle!. Is there anyway I have a sliding drawer without a default handle?
-----SOLUTION----
draw = (SlidingDrawer)findViewById(R.id.slidingDrawer1);
//Close the draw if opened when the user touches elsewhere on the screen
draw.setOnTouchListener(new OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
if(draw.isOpened())
((SlidingDrawer)v).animateOpen();
return false;
}});
//Open the draw by external button
((Button) findViewById(R.id.quiz_button)).setOnClickListener(
new Button.OnClickListener(){
#Override
public void onClick(View arg0) {
draw.animateOpen();
} });
An the XML for the sliding draw view was:
<SlidingDrawer android:layout_width="fill_parent" android:allowSingleTap="false" android:id="#+id/slidingDrawer1" android:content="#+id/content" android:handle="#+id/handle" android:layout_height="fill_parent" android:layout_alignParentTop="true" android:layout_alignParentLeft="true">
<Button android:layout_height="wrap_content" android:layout_width="0px" android:visibility="invisible" android:text="Close" android:id="#+id/handle"></Button>
<LinearLayout android:id="#+id/content" android:gravity="center" android:background="#4FFFFF44" android:layout_width="fill_parent" android:layout_height="76dp"></LinearLayout>
</SlidingDrawer>
Many Thanks
Sam
I tried for many hours and failed to get rid of the handle, the best I could do wass move it far away from the view window. If you have already extended the slidingdrawer class it should be easy.
In the onLayout method find the line
handle.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
and change it to
handle.layout(10000, 10000, 10000, 10000);
Basically its just setting its position to way of screen.
I found a better way to fix the problem.
Do not hide a handle itself, but it's content. I had an ImageView as a handle, but I changed it to a LinearLayout holding an ImageView.
<LinearLayout
android:id="#id/handle"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/handleImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/sliding_drawer_handle" />
</LinearLayout>
Now handleImage.setVisibility(View.INVISIBLE) works fine in onAnimationEnd.
Hope that helped :)
I have the same problem, I don't want to show the handle because I have a personal button that shows the SlidingDrawer at the click. So, I solve it setting the handle height to 0dp.
This is my handle code:
<ImageButton
android:id="#+id/cash_menuGruop_handle"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_contetn"
android:layout_height="0dp"/>
<Button
android:layout_width="0dp"
android:layout_height="0dp"
android:id="#+id/handle"
android:visibility="gone" //DOES NOT WORK
</Button>
use height and width 0dp
,for open and close use handle.performclick();
it is working for me