i want to Call Android Layout(XML) Programmatically in a function.
Layout is already Created in XML. i am asking this question because i don't want to use this in Android Native app, actually i will call these layouts in Unity3D which is a Gaming Engine. So Let say that i have a layout. For Example look at below code:
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/useful_nums_item_name"/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/useful_nums_item_value"/>
</LinearLayout>
<ImageButton
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="#drawable/call"
android:id="#+id/call_btn"
android:onClick="callNumber"/>
</LinearLayout>
Now i want to create a function which can call this layout. But But i don't want to use below code as i am not going to use in Android Native App.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
i will directly use the Unity3D class as below:
public class MainActivity extends UnityPlayerActivity {
}
So i need to call my layout in that class but in form of Some Function. For Example:
public class MainActivity extends UnityPlayerActivity {
public void ShowLayout(){
enter code here
}
}
So i need you people help to solve this problem.
Any help will be appreciated.
Take your layout with the use of inflator and then bring it on front.
LayoutInflater inflater = LayoutInflater.from(context);
View yourView = inflater.inflate(R.layout.popup_layout, null, false);
// then bring it to front
yourView.bringToFront();
Define your view / layout without XML instead. In your case, you could define it in the ShowLayout() method. This code should point you in the right direction:
LinearLayout layout = new LinearLayout(getContext());
layout.setWeightSum(1);
LinearLayout childLayout = new LinearLayout(getContext());
LinearLayout.LayoutParams childParams = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 0.8f);
childLayout.setLayoutParams(childParams);
LinearLayout.LayoutParams fieldParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
TextView name = new TextView(getContext());
name.setLayoutParams(fieldParams);
TextView value = new TextView(getContext());
name.setLayoutParams(fieldParams);
LinearLayout.LayoutParams buttonParams = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 0.2f);
ImageButton call = new ImageButton(getContext());
call.setLayoutParams(buttonParams);
call.setImageResource(getResources().getDrawable(R.id.call));
Related
I have an Android app which can create multiple lines each of which contains two spinners and an EditText. If the content gets too wide for the EditText, it breaks into multiple lines and this messes up my layout. So I call setMaxLines(1). But now the EditText scrolls internally. I want the EditText to expand horizontally to fit its content and the containing HorizontalScrollView to scroll. How can I do this?
I tried putting a HorizontalScrollView in a ScrollView and vice versa. Neither way round works. I expected that setting (both) LayoutParams to wrap_content would work but it doesn't.
I haven't included all of the code because it is a big app. Here is the layout XML:-
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- This is an invisible view to request the focus when an EditText gets deleted
in order to stop Android highlighting something else.
It would be nicer to go back into touch mode,
but Android does not provide a way of doing that. -->
<TextView
android:layout_width="1dp"
android:layout_height="1dp"
android:text=""
android:alpha="0"
android:id="#+id/defineinvisible"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/defineclasslayout">
</LinearLayout>
</LinearLayout>
</ScrollView>
</HorizontalScrollView>
The lines containing the EditTexts are added dynamically because the number of them can vary as the app runs.
The code to add a line looks a bit like this (I've left out some irrelevant detail):-
public class OrItem extends LinearLayout implements TextWatcher {
public OrItem(Context context) {
m_nameSelector = new Spinner(m_context);
m_contSelector = new Spinner(m_context);
m_matchString = new EditText(m_context);
m_matchString.setHorizontallyScrolling(false); m_matchString.setMaxLines(1);
m_matchString.setInputType(TYPE_CLASS_TEXT);
}
public setup(...) {
ViewGroup.LayoutParams ww = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
setOrientation(LinearLayout.HORIZONTAL);
addView(m_nameSelector, ww);
addView(m_contSelector, ww);
m_matchString.setText(sa[2]);
m_wasEmpty = sa[2].isEmpty();
m_matchString.addTextChangedListener(this);
addView(m_matchString, ww);
}
}
The OrItem is added under a hierarchy of LinearLayouts that hangs from defineclasslayout.
I tried inserting
but this goes back to line wrapping inside the EditText.
I found workaround for this. I make each individual line a HorizontalScrollView. Then I can scroll a long line. This is less elegant than scrolling the whole view, but it works.
public class OrItem extends HorizontalScrollView implements TextWatcher {
public OrItem(Context context) {
m_layout = new LinearLayout(context);
m_nameSelector = new Spinner(context);
m_contSelector = new Spinner(context);
m_matchString = new EditText(context);
m_matchString.setMaxLines(1);
m_matchString.setInputType(TYPE_CLASS_TEXT);
m_matchString.setHorizontallyScrolling(false);
}
public boolean setup(...) {
ViewGroup.LayoutParams ww = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
addView(m_layout);
m_layout.setOrientation(LinearLayout.HORIZONTAL);
m_layout.addView(m_nameSelector, ww);
m_layout.addView(m_contSelector, ww);
m_matchString.addTextChangedListener(this);
m_layout.addView(m_matchString, ww);
}
I'm trying to add a bunch of ImageView on my UI using a loop, the problem is that I have no Idea if the ImageView is being added or not because when I run the app it just gives me a blank white screen.
for(int i = 0; i < jsonArray.length(); i++) {
Log.d("test", "ok"); //the loop works btw
poster.setId(i);
JSONObject jsonObject = jsonArray.getJSONObject(i);
ImageView poster = new ImageView(getApplicationContext());
poster.setBackgroundResource(R.drawable.myPoster);
RelativeLayout.LayoutParams posterParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT
);
posterParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
posterParams.addRule(RelativeLayout.CENTER_VERTICAL);
posterParams.width = 160; //is this DP?
posterParams.height = 220;
relativeLayout.addView(poster, posterParams);
}
Any suggestion is welcome.
EDIT
I added another piece of code just to test if a widget will be added without using a loop:
//test
LinearLayout layout = new LinearLayout(this);
Button btn = new Button(this);
btn.setText("this is a button");
btn.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
layout.addView(btn);
And I still get the same result, just blank.
First of all, you are giving exactly the same parameter to each ImageView this causes all your ImageView lays on Like STACK only the last one will be visible to you. You may use ScrollView to see if the ImageViews actually added to your root layout
Secondly, set layout parameters to your dynamic ImageViews not your root layout.
Update
How to use ScrollView,
First of all, your XML should contain ScollView and a child (LinearLayout in our case but you can choose any layout depending on your use case) for placing your ImageView
<ScrollView>
<LinearLayout
android:id = "imageViewPlaceHolder">
</LinearLayout>
</ScrollView>
Secondly, in your Java code, you should find an inner layout to add views as follows
LinearLayout placeHolder = findViewById(R.id.imageViewPlaceHolder);
Then you are ready to add ImageViews into placeHolder since your placeHolder wrapped with ScrollView it will create a scroll dynamically if the content height goes beyond the dedicated height.
placeHolder.addView(yourImageView);
Adding everything from Java
HorizontalScrollView hsv = new HorizontalScrollView(context);
hsv.setLayoutParams(yourLayoutParams);
LinearLayout myPlaceHolder = new LinearLayout(context);
myPlaceHolder.setLayoutParams(yourLayoutParamsForLinearLayout);
myPlaceHolder.addView(yourDesiredImageView);
hsv.addView(myPlaceHolder);
yourRootLayout.addView(hsv);
Hope it makes sense, feel free to ask any clarification
try this:
listView = (ListView) findViewById(R.id.lv_info);
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, text);
listView.addHeaderView(creatHeader(getString(R.string.abuot_email),getResources().getString(R.string.email_info)));
listView.addHeaderView(creatHeader(getString(R.string.about_phone),getResources().getString(R.string.admin_phone_num)));
listView.addHeaderView(creatHeader(getString(R.string.about_copyright), getResources().getString(R.string.copyright_info)));
listView.addHeaderView(creatHeader(getString(R.string.about_version),getResources().getString(R.string.version_info)));
listView.setAdapter(adapter);
Method creatHeader:
public View creatHeader(String title, String text) {
View v = getLayoutInflater().inflate(R.layout.lv_item_header_info, null);
((TextView) v.findViewById(R.id.tvTitle)).setText(title);
((TextView) v.findViewById(R.id.tvText)).setText(text);
return v;
}
Layout file for items:
<?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:padding="#dimen/activity_vertical_margin">
<TextView
android:id="#+id/tvTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ssss"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"/>
<TextView
android:id="#+id/tvText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="sssssssss"
android:gravity="center_vertical"/>
</LinearLayout>
I'm trying to create an app where I can put several times the same kind of layout in a LinearLayout.
The layout just has a TextView and i'm trying to use setText but this line of code doesn't seems to work.
I don't know how many layout I must add to the LinearLayout because it depends of how many drones (I have one layout/drone) the user will have upload to the app, so I made a function that read the text to put in the TextView from a SharedPreference and that also read the number of drones (so the number of layouts) in another SharedPreferences.
The TextView i'im putting the string in is from a layout named dronelayoutmain.
I tried sending just "test" in the setText, but it crashes anyway, so I think that android just can't find my TextView, but I don't really know why.
So here is the function I call in OnCreate that is supposed to add one layout for each drone I have
public void affichagedrone(){
LinearLayout mlineairelayout = (LinearLayout)
findViewById(R.id.lineaireLayout);
LinearLayout.LayoutParams params = new
LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
Context mContext;
mContext = getApplicationContext();
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
SharedPreferences droneprefs = mContext.getSharedPreferences("dronepref", MODE_PRIVATE);
SharedPreferences applimaindata = mContext.getSharedPreferences("applimaindata", MODE_PRIVATE);
int nbdrone = applimaindata.getInt(String.valueOf(emplacementNbDrone),1);
String string;
TextView textViewnomConstructeurDrone;
if (nbdrone !=0) {
for(int i=0;i<nbdrone;i++) {
textViewnomConstructeurDrone = (TextView) findViewById(R.id.textViewNomConstructeur);
string = droneprefs.getString(String.valueOf(i),"Fail");
textViewnomConstructeurDrone.setText(string);
final View rowView = inflater.inflate(R.layout.dronelayoutmain, null);
// Add the new row before the add field button.
mlineairelayout.addView(rowView);
}
}
}
And here is the layout i'm trying to put in the LinearLayout.
<?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="120dp"
>
<TextView
android:id="#+id/textViewNomConstructeur"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:text="#string/adddrone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
The function is supposed to check in applimaindata the number of layout to add, and then, in the for(), is supposed to set the Text of the TextView from the droneprefs file and then add the Layout to the main LinearLayout
If this TextView belongs in the newly inflated layout, you must find it after the layout is inflated:
for(int i = 0; i < nbdrone; i++) {
final View rowView = inflater.inflate(R.layout.dronelayoutmain, null);
textViewnomConstructeurDrone = rowView.findViewById(R.id.textViewNomConstructeur);
string = droneprefs.getString(String.valueOf(i),"Fail");
textViewnomConstructeurDrone.setText(string);
mlineairelayout.addView(rowView);
}
This is suppose to be a scroll view with all the content added from the Java code when response is received from the API.
The problem is that I can't find a way to display the information like this in a ScrollView. I tried using an ImageButton but I couldn't get the content in it then I tried using a Button but still couldn't achieve the desired effect please can someone suggest a way I could do this.
private Button makeButton(String targetName, final String i, LinearLayout.LayoutParams buttonLayoutParams) {
Button in = new Button(this);
in.setBackground(getResources().getDrawable(R.drawable.rectangle14));
in.setText(targetName);
in.setWidth(360);
in.setHeight(72);
in.setLayoutParams(buttonLayoutParams);
in.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent myIntent = new Intent(HomeActivity.this,XSavingDetailsActivity.class);
myIntent.putExtra("i" ,i);
HomeActivity.this.startActivity(myIntent);
}
});
return in;
}
You should use a RecyclerView .Each and every component within the RecyclerView is a CardView . Also you should learn about Material Design.
Apart from the above some useful links:
https://developer.android.com/guide/topics/ui/layout/cardview.html
https://www.androidhive.info/2016/01/android-working-with-recycler-view/
https://medium.com/#nileshsingh/android-cardview-101-everything-you-should-know-5bbf1c873f5a
Just make the top-level layout a ScrollView:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:stretchColumns="1">
<!-- everything else -->
</TableLayout>
I am creating an extremely simple Android application to serve as a proof of concept and a reference for an application I will create in the future.
My goal is to create a ListView, each item containing a TextView and a Button that, when pressed, makes a Toast pop up displaying the content of the TextView.
Here is my code and xml:
main.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="fill_parent"
android:orientation="vertical">
<ListView
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="#+id/mainListView1"/>
</LinearLayout>
entry.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="fill_parent"
android:gravity="center_vertical"
android:orientation="horizontal"
android:id="#+id/entryLayout"
>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/entryTextView1"
android:padding="10dp"
android:textSize="25sp"/>
<ImageButton
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="#android:drawable/ic_menu_close_clear_cancel"
android:id="#+id/entryImageButton"
/>
</LinearLayout>
MainActivity.Class
public class MainActivity extends Activity{
/* Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Set main.xml as user interface layout
setContentView(R.layout.main);
String[] companies = new String[] { "Test1", "Test2", "Test3",
"Test4", "Test4", "Test6", "Test7", "Test8", "Test9", "Test10"};
ArrayList<LinearLayout> views = new ArrayList<LinearLayout>();
for(int x=0; x!= companies.length-1; x++){
LinearLayout layout = (LinearLayout) findViewById(R.id.entryLayout);
TextView text = (TextView) layout.getChildAt(0);
text.setText(companies[x]);
ImageButton button = (ImageButton) layout.getChildAt(1);
button.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v){
LinearLayout layout = (LinearLayout) v.getParent();
TextView view = (TextView) layout.getChildAt(0);
Toast.makeText(MainActivity.this,view.getText(), Toast.LENGTH_SHORT).show();
}
});
views.add(layout);
}
ListView listView = (ListView) findViewById(R.id.mainListView1);
for(LinearLayout layout: views){
listView.addView(layout);
}
}
I get an Kin the line
TextView text = (TextView) layout.getChildAt(0);
And for the life of me I can't figure out why. This is likely due to my lack of knowledge to how certain functions in the API work.
Your immediate issue is that findViewById looks in the layout you've inflated with setContentView() and since the Views you are trying to inflate aren't in that layout, they return null.
So this line returns null
LinearLayout layout = (LinearLayout) findViewById(R.id.entryLayout);
which causes a NPE at this line as you've noticed
TextView text = (TextView) layout.getChildAt(0);
because layout is null.
The bigger issue is the way you are going about using your ListView. Since you want to use a custom layout for the rows, you should be using a custom Adapter and inflate the appropriate layout there . You can then utilize Adapter's getView() method to set the data in each row as needed.
This tutorial can help you get started on that.
You also may want to watch Google I/O World of ListView
ListView Docs