I m inflating 4 linear layouts multiple times in a scroll view. Each layout has a title in its header. The code snippet is given below.
for(int j=0;j<qType.length;j++)
{
LinearLayout.LayoutParams siz = new LinearLayout.LayoutParams(width, height);;
if(qType[j]==0)
{
view1 = getLayoutInflater().inflate(R.layout.layout1, main_layout,false);
siz = new LinearLayout.LayoutParams(width, height/3);
}
else if(qType[j]==1)
{
view1 = getLayoutInflater().inflate(R.layout.layout3, main_layout,false);
siz = new LinearLayout.LayoutParams(width, height/3);
}
else if(qType[j]==2)
{
view1 = getLayoutInflater().inflate(R.layout.layout4, main_layout,false);
siz = new LinearLayout.LayoutParams(width, height/3);
}
else if(qType[j]==3)
{
view1 = getLayoutInflater().inflate(R.layout.layout5, main_layout,false);
siz = new LinearLayout.LayoutParams(width, height/2);
}
siz.topMargin = 25;
main_layout.addView(view1, siz);
}
scroll_layout.addView(main_layout);
scroll_layout.setBackgroundResource(R.drawable.options_background);
setContentView(scroll_layout);
Now there is textview in each layout and i want to change the text of it. If i access them by findviewbyid and give settext, only the first instance is being changed, i want to change the textview on all occasions.
for(int k=0;k<NumberQuestions.length;k++)
{
TextView number_title = (TextView)main_layout.findViewById(R.id.number_title);
TextView mcq_title = (TextView)main_layout.findViewById(R.id.mcq_title);
TextView comment_title = (TextView)main_layout.findViewById(R.id.comment_title);
TextView cam_title = (TextView)main_layout.findViewById(R.id.cam_title);
if(qType[k]==0)
{
number_title.setTypeface(myriadpro_bold);
number_title.setText(NumberQuestions[k]);
}
if(qType[k]==1)
{
comment_title.setTypeface(myriadpro_bold);
comment_title.setText(NumberQuestions[k]);
}
else if(qType[k]==2)
{
mcq_title.setTypeface(myriadpro_bold);
mcq_title.setText(NumberQuestions[k]);
}
else if(qType[k]==3)
{
cam_title.setTypeface(myriadpro_bold);
cam_title.setText(NumberQuestions[k]);
}
Please help.
probably the TextView android: id in all layouts are the same, thus explaining the behavior of the method findViewById always returns the first occurrence
Disclaimer: I feel like you are trying to work against the Android Framework, as opposed to working with it. My suggestion is a tad bit of an overhaul, but I do feel like it is the correct way to go about things.
I would recommend using a ListView, since you are repeating the same format many times. A listview will typically have a container of objects of objects, and an adapter responsible for mapping an object to a particular row within the listview. When you change the data in the underlying container, you will call the callback notifyDataSetChanged() for your adapter to notify it that you changed the underlying data and alert it to update your listview.
2 great resources/tutorials from the android developer site:
ListView: http://developer.android.com/guide/topics/ui/layout/listview.html
Adapters: http://developer.android.com/guide/topics/ui/declaring-layout.html#AdapterViews
If i am right main_layout is a name view in your xml file.So You should use like this
view1 = getLayoutInflater().inflate(R.layout.layout1, main_layout,false);
TextView tv = (TextView)main_layout.findViewById(R.id.tv1);
where tv is texview in layout1.xml
Related
I have added multiple TextViews dynamically in a layout,
for(int x=4;x<result.length();x++)
{
JSONObject collegeData = result.getJSONObject(x);
Log.i("Classlist",""+x);
TextView tv = new TextView(this);
Animation animation = AnimationUtils.loadAnimation(student_profile.this, android.R.anim.slide_in_left);
tv.startAnimation(animation);
tv.setTag(tag);
tv.setLayoutParams(lparams);
tv.setText(collegeData.getString("date") + " " + collegeData.getString("day_name"));
tv.setTextSize(17);
this.linearLayout_top5classes.addView(tv);
}
This loop adds textViews according to the data received by the url,Now i want to remove the textviews which were created in this loop and i cant find a proper method to do so....I only want to remove these textviews and not all the textviews
UPDATE
First i used
int prv=0;
then
String tag ="textView_"+x;
prv++;
in the first loop to generate multiple tags
then i removed them with
for(int x=4;x<prv;x++)
{
View view = this.linearLayout_top5classes.findViewWithTag("textView_"+x);
this.linearLayout_top5classes.removeView(view);
Log.i("prv value",prv+"");
}
Of course there is a way. Just look for child views with tag:
View view = this.linearLayout_top5classes.findViewWithTag(tag);
this.linearLayout_top5classes.removeView(view);
If you add ID's to child views, then:
View view = this.linearLayout_top5classes.findViewById(id);
this.linearLayout_top5classes.removeView(view);
If possible try using different layout for the dynamically added textviews. and then remove views from second layout only. By using,:
linearLayout_top5classes.removeAllViews();
To remove particular view with tag
View view = this.linearLayout_top5classes.findViewWithTag(tag);
this.linearLayout_top5classes.removeView(view)
To remove view from particular position
this.linearLayout_top5classes.removeViewAt(position);
Use following logic to remove any view from layout.
this.linearLayout_top5classes..post(new Runnable() {
public void run() {
this.linearLayout_top5classes..removeView(view);
}
});
I am working on an e-commerce App . Here I am working on Products Filtering .
Here filters are dynamic, It means once filter page will display BRANDS and PRICE then next time it can display BRANDS , PRICE , STYLES ..etc .
There may be many cases to filter products .
Application is receiving filters dynamically from Webservice .
So here I am creating filters dynamically using data received from the webservice . For this I am using RecyclerView to display dynamic filters
.
Here is the code of RecyclerView where I am creating filters dynamically .
onCreateViewHolder() :
#Override
public FilterViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LinearLayout topLayout = new LinearLayout(mContext);
topLayout.setOrientation(LinearLayout.VERTICAL);
if (filterItems != null) {
for (int filterItemsCount = 0; filterItemsCount < filterItems.size(); filterItemsCount++) {
LinearLayout ll = new LinearLayout(mContext);
ll.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(10, 10, 10, 10);
AFileterItem filterItem = filterItems.get(filterItemsCount);
TextView textView = new TextView(mContext);
textView.setText(filterItem.getFiletrLabel());
ll.addView(textView);
for (int i = 0; i < filterItem.getList().size(); i++) {
VlauesItem item1 = filterItem.getList().get(i);
CheckBox cb = new CheckBox(mContext);
cb.setId(i);
cb.setText(item1.getValueItemLabel());
cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Toast.makeText(mContext, String.valueOf(isChecked), Toast.LENGTH_SHORT).show();
}
});
ll.addView(cb);
}
topLayout.addView(ll);
}
}else{
topLayout.addView(null);
}
FilterViewHolder viewHolder = new FilterViewHolder(topLayout);
return viewHolder;
}
Now , the problem is :
When I create filters dynamically then RecyclerView creates same filter more than once .
I want to know how should I manage above code so that I can eliminate this problem .
You need to understand what ViewHolders are. ViewHolder of a concrete type has single layout. If it is possible consider creating different viewholder types, or one with predefined layout, which will be customized in onBind callback. What you see is happening, because RecyclerView reuses view, and calls onCreateViewHolder only to fill the screen with items, then they are reused.
I have created checkbox dynamically. Based on the require list size just am creating new dynamic check box in a repeated manner and am also setting the Id for that. Now i want to do check it in other loop.
for(int i=0;i<require.size();i++)
{
//From Requirements
requirement=require.get(i);
RelativeLayout rl1 = new RelativeLayout(getActivity());
rl1.setBackgroundResource(R.drawable.listviewdesign);
l1.setOrientation(LinearLayout.VERTICAL);
req1 = new CheckBox(getActivity());
rl1.addView(req1);
req1.setId(Integer.parseInt(requirement.r_id));
Log.i("getid",Integer.toString(req1.getId()));
li.add(Integer.toString(req1.getId()));
}
In this loop am just checking element of li and proj_require1 values. If both are equal then I want to make the CheckBox as checked. For that i have written the code here.
for(int i=0;i<li.size();i++)
{
//li.get(i);
req1 = (CheckBox) container.findViewById(i);
String sr = req1.toString();
for(int j=0;j<proj_require1.size();j++)
{
pr = proj_require1.get(j);
if(sr.equals(pr.rid))
{
req1.setChecked(!req1.isChecked());
}
else
{
req1.setChecked(req1.isChecked());
}
}
}
But my doubt is in first loop am creating the CheckBox based on the size of require object. So every time it creates the CheckBox inside the loop. But in second loop am trying to access the checkbox which am created in the first loop. Could anyone please help me to solve this problem? The only way is i can create the CheckBox in the first loop. I want to access it in other loop. Is it possible?
I'm making an app that stores results in a multiple textviews,
First, I need to get the views, they are 20 views named result 1, .... result 20.
how can i get them to an array of textview.
I found this method but it's too long
TextView [] results = {(TextView)findViewById (R.id.result1),
(TextView)findViewById (R.id.result2),(TextView)findViewById (R.id.result3),
(TextView)findViewById (R.id.result4),(TextView)findViewById (R.id.result5),
(TextView)findViewById (R.id.result6).....};
thank you for help
How you started is correct, now think about putting that repetitive code in a cycle.
For example design a method that will take as the input an array of your TextView resources, and using a "for" cycle find that view by corresponding id.
private TextView[] initTextViews(int[] ids){
TextView[] collection = new TextView[ids.length];
for(int i=0; i<ids.length; i++){
TextView currentTextView = (TextView)findViewById(ids[i]);
collection[i]=currentTextView;
}
return collection;
}
And then you use it like this:
// Your TextViews ids
int[] ids={R.id.result1, R.id.result2, R.id.result3};
// The resulting array
TextView[] textViews=initTextViews(ids);
if you have a handle to parent the layout that contains the text views, you can recursively discover them with a function like this,
void getTextViews(View view, List<TextView> textViews) {
if (view instanceof TextView) {
textviews.add((TextView)view);
else if (TextView instanceof ViewGroup) {
getTextViews((ViewGroup)view, textViews);
}
}
now call it like this,
ViewGroup topLayout = findViewById(...);
List<TextView> views = new ArrayList<TextView>();
getTextViews(topLayout, views);
TextView[] textViewArray = textViews.toArray(new TextView[0]);
this is quite a bit longer, but it has the advantage of not needing to change the code if you add, remove, or rename a textview.
IMHO, don't focus on writing less code, focus on writing clear code. the speed at which you type is rarely the limiting factor in your productivity.
I have a java app that adds views dynamically to a container panel as follows.
void addBoard(int ID) {
BoardPanel p = new BoardPanel(myManager,ID);
setAutoLayout();
containerPanel.add(p);
containerPanel.repaint();
}
When I try to convert this to an android app it hangs when addView is called. What is the problem? Note that the user could add a 1000 views (BoardPanels) if he likes so I can not use XML layouts.
void addBoard(int ID) {
BoardPanel p = new BoardPanel(context,myManager,ID);
Log.i("Info", "Going to add view");
containerPanel.addView(p);
Log.i("Info", "Added");
containerPanel.postInvalidate();
}
Thanks
Update: Problem seems to be due to threaded code as Aegonis pointed out.
Try ViewGroup.addView() (FrameLayout, GridLayout, LinearLayout, ... are all extensions of ViewGroup).
For example, if you want a View to be inserted after the first already existing View:
LinearLayout layout = (LinearLayout) findViewById(R.id.layoutID);
layout.addView(viewToBeAdded, 1);