there is some way to make my own item in xml? - java

i work on android-studio project, and my question is about if
there is some way i can define in xml type of some item that contain
few edit text and buttons, and open listview that contain the item i create?
somthing like :
<item
<Editext(some setting)/>
<Edittext 1(some setting)/>
<Button(some setting)/>
/>
and then some adapter that adjust or something like that, that i can add to ListView.
i saw in youtube some videos that try to explain that but i get stock.. i dno't really get this.

This took my a while to figure out, but it works.
Create your Layout file just however you want. Save it as res/layout/something.txt. Example:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:text="hello"
android:layout_height="wrap_content"
android:layout_width="150dp"
android:id="#+id/text1"/>
<TextView
android:text="world"
android:layout_height="wrap_content"
android:layout_width="150dp"
android:id="#+id/text2"/>
</LinearLayout>
Use it in your code as follows:
LinearLayout mainLinearLayout = new LinearLayout(getApplicationContext());
// inflate your container
View view = inflater.inflate(R.layout.something, null);
// you can make changes to the elements like this:
TextView txt1 = (TextView) view.findViewById(R.id.text1);
TextView txt2 = (TextView) view.findViewById(R.id.text2);
view.setTag(tag);
// add to main layout
mainLinearLayout.addView(view);
Where tag is an unique integer to identify the View. You don't need to set the tag if you're using the container only once.
I didn't use an Adapter when I made this. I just used a ScrollView to make a continous list of entries. Change this to your needs.

Related

Android - FirebaseListAdapter duplicating runtime layout changes

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);
}

Android way to add new xml layout

I have an activity with a layout. After a GET request to a server, I want to dynamically add new elements to that layout.
I want to add those elements multiple times, using a for-structure.
The elements I want to add are the following:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="64dp"
android:background="#drawable/outer_border"
android:padding="2dp"
android:layout_marginTop="20dp">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="#color/orange"
android:height="40dp"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:text="TW"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#ffffff"
android:textSize="70px"
android:width="60dp" />
<CheckBox
android:id="#+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/textView3"
android:layout_toLeftOf="#+id/checkBox1"
android:text="inca 6 zile"
android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
I've tried this:
for(int i = 0; i < homeworkList.size(); i++){
LinearLayout linearLayout = (LinearLayout) currentActivity.findViewById(R.id.linearLayout2);
RelativeLayout newLayout = new RelativeLayout(currentActivity, null, R.style.HomeworkLayout);
TextView text = new TextView(currentActivity);
TextView text1 = new TextView(currentActivity);
text1.setText("da");
text.setText("nu");
newLayout.addView(text1);
newLayout.addView(text);
linearLayout.addView(newLayout, relativeParams);
}
But no result, those textview were added but on top of each other, and the relative layout I just added in that for doesn't have any of the style I added using R.style.HomeworkLayout.
What is the best way to add the elements with so much styling? Why isn't this working?
those textview were added but on top of each other
That's what you told RelativeLayout to do. If you wanted to specify positioning rules, you would have passed instances of RelativeLayout.LayoutParams to addView() when you were adding the TextView widgets.
What is the best way to add the elements with so much styling?
Well, probably, the answer is to use ListView or RecyclerView. That being said, the simplest solution that keeps your vertical LinearLayout would be to inflate the rows:
LinearLayout linearLayout = (LinearLayout) currentActivity.findViewById(R.id.linearLayout2);
for(int i = 0; i < homeworkList.size(); i++){
View row=getLayoutInflater().inflate(R.layout.row, linearLayout, false);
// call findViewById() to retrieve your TextView widgets and fill them in
linearLayout.addView(row);
}
This assumes that the layout you show in your question is named R.layout.row; adjust the inflate() call as needed if that is not the name. This also assumes that the code snippet is in a method on the activity that is hosting this UI.
If you want to use a layout which is repeating why don't you prefer using a custom liner layout.
A simple and basic solution is mentioned on this link
http://android-coding-tuts.blogspot.in/2012/02/custom-listview-with-sliding-view-for.html
You should look up Fragments for this. They have a separate control-view structure and you can just create a new fragment for each subview.
Check it out here:
http://developer.android.com/guide/components/fragments.html

Android Tutorials -- Why does my app crash when I try to access an existing Text View

I am going through the Android tutorial here. I have no problem implementing it the way they have. But, I am trying to understand why this other way fails. If I enable the two commented out lines and comment out the lines after them as noted, my app crashes. It seems to me that I should be able to reference an existing text view by ID, set its text, and then set the content view to be the layout that contains the text view I have referenced. I am sure I am thinking about this the wrong way, but I'd like some clarification on why it doesn't work.
String message = intent.getStringExtra(MyActivity.EXTRA_MESSAGE);
//TextView textView = (TextView)findViewById(R.id.text_view);
TextView textView = new TextView(this); //comment this out
textView.setTextSize(40);
textView.setText(message);
//setContentView(R.layout.activity_display_message);
setContentView(textView); //comment this out
and my xml
<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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.<myname>.myfirstapp.DisplayMessageActivity">
<TextView
android:id="#+id/text_view"
android:text="#string/hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
It seems to me that I should be able to reference an existing text view by ID, set its text, and then set the content view to be the layout that contains the text view I have referenced
The logic is wrong. Only after setContentView() is called, the findViewById() can be used to get view from layout file, and then the view's methods can be called.
Your intent.getStringExtra(MyActivity.EXTRA_MESSAGE) can be called anywhere in OnCreate(), so there is nothing wrong about its position.

Inflated layout's children not showing

I am using a DraggableGridView from here.
What I did before was add a simple programmatically built ImageViews to the grid. That works perfectly fine.
I am now trying to add a Layout instead. I tried RelativeLayout, Framelayout, FrameLayout inside of a RelativeLayout.
Here is my code as of now:
/**
* Rebuild the grid view, e.g. after the adapter has been filled or a backup is restored
*/
private void renewGrid()
{
dgv.removeAllViews();
for(int i = 0; i < adapter.getCount(); i++)
{
LayoutInflater inflater = (LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
dgv = (DraggableGridView) inflater.inflate(R.layout.grid_item_layout, dgv);
FrameLayout fl = (FrameLayout) dgv.findViewById(R.id.grid_images);
ImageView icon = (ImageView) fl.findViewById(R.id.qstile);
icon.setImageDrawable(res.getDrawable(res.getIdentifier("qstile_" + adapter.getItem(i), "drawable", packagename)));
}
}
Following the grid_item_layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal" >
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/grid_images">
<ImageView
android:layout_width="32dp"
android:layout_height="32dp"
android:src="#drawable/icon_delete"/>
<ImageView
android:id="#+id/qstile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</FrameLayout>
<TextView
android:id="#+id/invisible_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text=""
android:visibility="gone" />
</RelativeLayout>
The RelativeLayout gets inflated into the grid nicely. I can observe this via DDMS and the "Dump view hierachy" function. The tree shows all RelativeLayouts inside the grid, but each of it doesn't have any children.
BUT... That is not true. If I step through the code and observe the inflated layouts I can see the children. So they are set up, get added just like told in the XML, but don't get drawn.
The OnItemClick listener on the children of the grid also works...
Any hint about what I'm missing here? I already tried several ways, even creating the complete layout programmatically and then adding it to the grid as children. Still no luck. None of the children get added.
Is that maybe an issue with the used DraggableGridView?
After searching for another few hours I found a fix in this SO thread
Basically I now extend DraggableGridView from FrameLayout rather than ViewGroup. This hasn't had any noticeable side effects to me.

android:animateLayoutChanges won't work in parent layout

Suppose I have a layout file structured like this:
<LinearLayout android:id="#+id/main" android:orientation="vertical" android:animateLayoutChanges="true">
<EditText>
<TextView android:id="#+id/header1">
<LinearLayout android:id="#+id/insertionPoint" android:orientation="vertical" android:animateLayoutChanges="true">
</LinearLayout>
<TextView android:id="#+id/header2">
</LinearLayout>
I want to dynamically add text fields to the Layout insertionPoint and I would like to see an animation of the elements below it (in this case, header2) sliding down.
Using android:animateLayoutChanges only animates the elements in the layout insertionPoint, so there is no animation for header2. What should I do?
Just to be more clear: what I would like to do here is something like the animations that we can see in the People app in ICS when we add more fields, like telephone numbers, to a contact.
Thank you!
API 16 added the LayoutTransition.CHANGING animation type, however it is disabled by default.
To enable:
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.main);
linearLayout.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
Nice DevBytes video: https://www.youtube.com/watch?v=55wLsaWpQ4g

Categories

Resources