i am designing an app for android tablets. I have created a layout file which contains the application bar, next is some buttons. In the middle of the screen i want to have a horizontal scroll view inside which i need to show some images.
The number of images inside the scroll view depends upon the return data from the url. For this i am maintaining an array list. According to the size of the array i need to create the image views withing the scroll view.
I have placed all other buttons, textviews in the layout file and i need to make the above said view alone through coding, how to do this.
If the array size is 19, then the list of images within scroll view to be shown in the following order only
1 4 7 10 13 16 19
2 5 8 11 14 17
3 6 9 12 15 18
In iPad iBook apps library page, the books will be listed out in this way.
how to do this....
not sure but can try approach like this
1- Create/inflate a horizontal scrollview ..
2- make for loop running i= 0 to x
where x= (totalCount/3)+(totalCount%3>0?1:0)
3- Create a Linear layout with orientation vertical
4- create one more loop form j=0 to 3 or (i+1)*3+j< totalCount
5- add your element layout in Linear layout
6 after the inner loop closed add Linear layout in horizontal scroll-view
loop termination condition like the value of x may not be exact please check them
For making item clickable
1- take any view from element layout like in you case image-view is good option
2- creates a class in you activity or better to extend you activity with clickListner.
3- while creating the imageView for each element set this listener to all
4- Set the data object or index with element with image-view in tad using SetTag
5- in Onclick function you will get image-view as argument and use getTag to get that data of attached with clicked element
Thanks to Dheeresh Singh
Following is my main.xml file
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/linear_1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal" >
</LinearLayout>
</HorizontalScrollView>
i have my Horizontal scroll view in my main.xml file
public class LayoutActivity extends Activity
//implements OnClickListener
{
ViewGroup layout;
LinearLayout lr;
int x;
int total = 4;
int count = 0;
LinearLayout lay;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
count = 0;
layout = (ViewGroup)findViewById(R.id.linear_1);
x = (total/3)+(total%3 > 0?1:0);;
for(int i = 0; i < x; i++)
{
lr = new LinearLayout(this);
lr.setOrientation(LinearLayout.VERTICAL);
layout.addView(lr);
for(int j = 0; j < 3; j++ )
{
count++;
final View child = getLayoutInflater().inflate(R.layout.inflateview, null);
lay = (LinearLayout)child.findViewById(R.id.threeByThree_tableRow1_1_Layout1);
lay.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Toast.makeText(getApplicationContext(), "selected id is "+child.getId(), Toast.LENGTH_SHORT).show();
}
});
lr.addView(child);
child.setId(count);
if(i == total)
{
break;
}
}
}
}
}
in the above code i have lr is the LinearLayout to display it in vertical order and View child is the data which i need to show in both vertical and horizontal order.
Thanks a lot Dheeresh Singh
Related
I followed the below link to dynamically add a layout multiple times using inflater and AddView()
Is there a way to programmatically create copies of a layout in android?
I used a loop to create multiple entries. But only one entry is comming up which is the result of last loop index
Below is my C# code
I can see only one child inside the parent which is the result of last loop.
What I missed?
var parent = FindViewById<RelativeLayout>(Resource.Id.ParentLayoutWrapper);
for (int i = 0; i < 4; i++)
{
var view = LayoutInflater.Inflate(Resource.Layout.RepeatingLayout, parent, false);
var txtView = view.FindViewById<TextView>(Resource.Id.textViewSample);
txtView.Text = i.ToString()+ " Android application is debugging";
txtView.Id = i;
parent.AddView(view, i);
}
The original post you worked from had a LinearLayout as the parent layout, not a RelativeLayout like you have. When you add a view (or another layout) to a LinearLayout, it gets positioned below (when LinearLayout has vertical orientation) any existing elements in the layout. However, the elements in a RelativeLayout need to use positioning properties to determine where they will be in the RelativeLayout, so every time you add the new layout, RepeatingLayout, since you are not changing the layout options, the view/layout is added over the existing view/layout. So change the parent layout to a LinearLayout in your layout file and then this should work:
LinearLayout parent = FindViewById<LinearLayout>(Resource.Id.parentLayout);
for (int i = 0; i < 4; i++)
{
var view = LayoutInflater.Inflate(Resource.Layout.RepeatingLayout, null);
var tv = view.FindViewById<TextView>(Resource.Id.textViewSample);
tv.Text = i.ToString() + " Android application is debugging";
parent.AddView(view);
}
Trying to do the same with a RelativeLayout as the parent layout highly complicates things unnecessarily.
My task is to generate several amount of buttons with fixed width and height.I decided to store these buttons in some ArrayList to use in the future. This is how I do it:
for(int i = 1 ; i<=n; i++)
{
Button place = new Button(this.context) ;
place.setTextColor(ContextCompat.getColor
(this.context,R.color.background_color));
place.setTypeface(typefaceForPlaces);
place.setId(i+0);
place.setBackgroundResource(R.drawable.real_place_background);
place.setLayoutParams(new
LinearLayout.LayoutParams(65,65));
places.add(place);
}
But problem is here
place.setLayoutParams(newLinearLayout.LayoutParams(65,65));
Here,width and height is set in pixels. But I need dp. I know code that
converts dp to pixels, but I do not think that it is good solution. Now,I have an idea to create some layout and store there my button's shape. Here is my layout for this called place_button.xml:
<?xml version="1.0" encoding="utf-8"?>
<Button
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/button_id"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#drawable/real_place_background"
android:textColor="#202020">
</Button>
And I created some View and inflated that button to this view. After that, I got the button above by its id and save it to another button,because I need a lot of such buttons. Then I needed to change new button's id. But i got following error:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.incubic.abay.clasico/com.incubic.abay.clasico.GameActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setId(int)' on a null object reference
Below is my code:
private void generatePlaces() {
View place_view = LayoutInflater.from(getContext()).inflate(R.layout.place_button,null);
for(int i = 1 ; i<=n; i++)
{
Button place = (Button)place_view.findViewById(R.id.button_id);
place.setId(i+0);
place.setTypeface(typefaceForPlaces);
places.add(place) ;
}
}
Everything happens in Fragment. generatePlaces method is called after onViewCreated. How to solve my problem?
Probably you have an issue due to absence of a Button id
<?xml version="1.0" encoding="utf-8"?>
<Button
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/button_id"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#drawable/real_place_background"
android:textColor="#202020"/>
UPDATE:
When you do inflation, you already get your Button view, no need to do findViewById.
In general I don't think inflating a view in your case is a good approach. Better create buttons:
private void generatePlaces()
{
for (int i = 1; i <= n; i++)
{
Button place = new Button(this.context);
place.setTextColor(ContextCompat.getColor(this.context, R.color.background_color));
place.setTypeface(typefaceForPlaces);
place.setId(i + 0);
place.setBackgroundResource(R.drawable.real_place_background);
place.setLayoutParams(new LinearLayout.LayoutParams(dpToPx(50), dpToPx(50)));
places.add(place);
}
}
private int dpToPx(int dp)
{
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
I think it is because you change the id of the button, on the next iteration you get a null pointer exception. I'd say create button views programmatically entirely, not from an xml and then append those to the parent view. Or look into something like listviews.
I'd say go with your earlier approach and refer to this question for converting to DP.
In my Project , I have 80 TextViews.
I should set their text from 1 to 80 once project runs , and they dont need to be changed in future.
Except TxtViews , I have some other things in my Layout, the TextViews are under ImagesViews. actually I have 80 imagesViews and under them are 80 TextViews. I want to set text of textViews from 1 to 80 dynamically.
I know I can do it in my layout.xml ,
but its really time consuming.
is there any way to do that by code?
for example with a for cycle or something like that?
Create a ViewGroup suitable for your needs in the layout, for example:
<LinearLayout
android:id="#+id/linear_layout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
Then you create you TextView instances programatically, and add them to the LinearLayout, like this:
LinearLayout layout = (LinearLayout)findViewById(R.id.linear_layout);
for(int i = 0; i < 80; i++) {
TextView textView = new TextView(getContext());
textView.setText("text" + i);
layout.addView(textView);
}
Optionally, you can add tags or whatever to locate them again. Alternatively just iterate over the layouts subviews.
If you know that 80 Textview fixed then you should take listview for that.
Listview Benefit
Memory management automatically
Listview manage indexing
If they share the same layout, except for the text, and could be displayed as a list, you could use an ArrayAdapter and pass the values from code.
http://www.mkyong.com/android/android-listview-example/
Checkout the below example,
public class MainActivity extends Activity {
LinearLayout linearLayout ;
ScrollView scrollView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scrollView = (HorizontalScrollView) findViewById(R.id.scrollViewActivityMain);
}
private void populateTextViews() {
linearLayout = new LinearLayout(this);
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
//add all textViews here
for(int i=0; i < 80; i++){
TextView myTextView = new TextView(this);
myTextView.setText("My TextView "+i);
myTextView.setGravity(Gravity.CENTER);
linearLayout.addView(myTextView);
}
scrollView.addView(linearLayout);
}
}
Don't forget to put that scrollView in your xml.
Let me know if it works for you...
If your TextViews are declared on the xml, wrap them on another view so you can reference it on the java code later, then simply use a for.
Something like:
View view = findViewById(R.id.your_wrapper);
for(int i=0; i<((ViewGroup)view).getChildCount(); i++) {
View nChild = ((ViewGroup)view).getChildAt(i);
TextView tv = (TextView) nChild;
tv.setText(String.valueOf(i + 1));
}
If not, you can simply create them dynamically inside your java code, and append them to a layout like LinearLayout.
Example:
xml
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/linear"
/>
Java code
LinearLayout ll = (LinearLayout) findViewById(R.id.linear);
for (int i = 1; i <= 80; i++) {
TextView tv = new TextView(this); // Assuming you're inside an Activity.
int count = ll.getChildCount();
tv.setText(String.valueOf(i));
ll.addView(tv, count, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
}
EDIT: But truly, you should use RecyclerView or ListView for that if your values are not going to change.
You can read more about RecyclerView here, and on ListView here.
Second edit: From what you're saying on your comments, you REALLY should be using ListView instead of your current design. The solutions above and from the other answers won't work at all for your problem.
I have a gridview that is made of of 31 cells. A user can select any combination of cells and then click on a button to save their selections. Once they click the save button a dialog box appears and asks them what they want to do next. Within this dialog is a edit text view. When the user clicks inside the edit text box the keyboard appears. When this happens only 21 of the 31 cells are visible on the screen and when I try to call the getChildrenCount() method of GridView class I only see 21 children. Can someone explain why this happens and what I can do to eliminate this issue? I have attached images in hopes that clarifies the issue. Below I have pasted a snippet of code where I am trying to get the child count of the gridview.
protected Set<String> getSelectedFrequencies() {
Set<String> selectedFrequencies = new HashSet<String>();
for(int i = 0; i < gridView.getChildCount(); i++) {
ViewGroup gridChild = (ViewGroup) gridView.getChildAt(i);
for(int k = 0; k < gridChild.getChildCount(); k++) {
if( gridChild.getChildAt(k) instanceof Button ) {
if(gridChild.getChildAt(k).isSelected()) {
selectedFrequencies.add(gridChild.getChildAt(k).getTag().toString());
}
}
}
}
return selectedFrequencies;
}
There is nothing really special about the code.
Are you using a softInputMode of pan or resize? With pan that will never happen. With resize, it could be that only 21 fit on screen, so the gridView creates only 21 children and does view swapping when you scroll. In case you didn't know, listview and gridview only create as many views as are needed to fit on the screen. When you scroll it just loads data for the new positions into the existing views.
So, I create table view in XML to which the rows are added dynamically using the following java code:
private void fillTable(TableLayout tableLayout, String[] items) {
for (int i = 0; i < items.length; i++) {
TextView itemText = new TextView(FillingActivity.this);
itemText.setText(items[i]);
TableRow row = new TableRow(FillingActivity.this);
row.addView(itemText);
if(i % 2 == 1)
row.setBackgroundColor(color.LightGreen);
tableLayout.addView(row);
}
}
The code for a single tablelayout is the following:
<TableLayout
android:id="#+id/dinnertableviewing"
android:layout_width="346dp"
android:layout_height="wrap_content"
android:layout_x="2dp"
android:layout_y="210dp" >
</TableLayout>
But then when add many items to that table it overlaps with the space for the next tables
here is a picture that shows it:
Don't use AbsoluteLayout. The difficulties you're running into when an AbsoluteLayout contains content that can resize or when you run on differently sized screens (e.g. just about every Android device in the wild) are exactly why AbsoluteLayout is deprecated.
If you're trying to position elements vertically down the screen as they fit, use a LinearLayout with android:orientation="vertical".