I want to implement custom listview in android that has row from smaller to bigger text as below.
If not listview/recyclerview then what other component of android can i use?
Any help will be appreciated.
For listview you will need something like this, after populating your list:
private void changeSizes() {
View v;
View v1;
TextView tv; // this one depends on your layout
TextView tv1;
int count = myList.getCount();
int middleRowIndex = (int)count/2 ;
TextView midRow = myList.getAdapter().getView(middleRowIndex, null, null).findViewById(R.id.textView);
midRow.setTextSize(TypedValue.COMPLEX_UNIT_SP,(int)(count * middleRowIndex));
int prevIndex = middleRowIndex - 1;
int nextIndex = middleRowIndex + 1;
while(prevIndex >=0 && nextIndex < count){
v = myList.getAdapter().getView(prevIndex, null, null);
tv = (TextView) v.findViewById(R.id.textview);
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP,(int)(count * prevIndex));
v1 = myList.getAdapter().getView(nextIndex, null, null);
tv1 = (TextView) v.findViewById(R.id.textview);
tv1.setTextSize(TypedValue.COMPLEX_UNIT_SP,(int)(count * prevIndex));
prevIndex--;
nextIndex++;
}
}
v,v1,tv and tv1 are views inside your custom listview so you might need to change them, also the way of calculating font sizes and setting it you might want to change it.
P.S i didn't try this code on an app, but it should work let me know in case you encountered some error.
Related
I'm trying to programmatically pass the id of a layout.xml file to the View.inflate method but am not sure how I could go about that. I have a test bit of code that I'm tring to get working and, as you'll see I've tried passing this in as a String but that doesn't work.
Any ideas? My thanks.
LinearLayout main = (LinearLayout) findViewById(R.id.mainLayout);
for (int i = 0; i < 3; i++) {
String boxToInflate="R.layout.box"+Integer.toString(i);
LinearLayout ll = (LinearLayout) View.inflate(MainActivity.this, boxToInflate, null);
main.addView(ll);
}
Edit: A few minutes later.
I think I may be making some progress with this test code:
// Get outer relative layout
LinearLayout main = (LinearLayout) findViewById(R.id.mainLayout);
for (int i = 0; i < 3; i++) {
// String boxToInflate="R.layout.box"+Integer.toString(i);
int resID = getResources().getIdentifier("box" + i, "id",
getPackageName());
LinearLayout ll = (LinearLayout) View.inflate(MainActivity.this,
resID, null);
main.addView(ll);
}
int layoutId = getResources().getIdentifier("box"+i, "layout", getPackageName());
It also works for other things like drawables ("drawable" instead of "layout"), etc. Just replace the second parameter.
EDIT : Saw your edit, just replace "id" with "layout" and you're good.
I am trying to edit the width of a TextView before it is getting loaded on the screen based on some score value. The requirement is like, based on the relative score value the text view should have width.
I have written the below code in onCreate() method of the activity as below,
{{{
TextView graph = (TextView) findViewById(R.id.predictionScoreGraph);
graph.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int score = 60;
UserData data = UserData.getInstance();
score = data.overallScore();
TextView graph = (TextView) findViewById(R.id.predictionScoreGraph);
int grossWidth = graph.getWidth();
Log.d(TAG, "Existing width of the text view is "
+ grossWidth);
LayoutParams existing = graph.getLayoutParams();
int fillWidth = (grossWidth * score) / 100;
Log.d(TAG, "Modified width is " + fillWidth);
graph.setWidth(fillWidth);
existing.width = fillWidth;
graph.setLayoutParams(existing);
graph.setBackgroundColor(getResources().getColor(
android.R.color.holo_green_light));
graph.getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
}
});
}}}
It works like a Gem!! But when I want to do it for more than one TextView objects, it is not changing the width of the TextView object.
Can somebody please help me on how to change width of multiple TextView objects?
Thanks,
Rather than using a GlobalLayoutListener, try overriding the onMeasure method of the Activity.
I'm trying to make a dynamic grid layout, it being API 10+ is the part that's been making it slow going. I tried to make it wrap automatically.. but in the end found it easier just to try to force it into a grid pattern using coordinates. This script was working by itself when I did the positioning at time of creation, but now I am trying to loop through each item as a sort. So if one item is deleted, they all float back into a grid without a hole in the middle.
Problem is, it seems the layout parameters are only applying to the last object.
Here's some base variables and onCreate setup:
int screenWidth;
int screenHeight;
int distStep = 130;
int leftPad = 20;
int numCols;
int baseID = 0;
android.util.DisplayMetrics metrics = this.getResources().getDisplayMetrics();
screenWidth = metrics.widthPixels;
screenHeight = metrics.heightPixels;
numCols = (int) (screenWidth - leftPad) / distStep;
int scrRemain = screenWidth - ((numCols * distStep) + leftPad);
distStep += (int) scrRemain / numCols;
Then on to the main function for adding:
public void addObjToLayout() {
RelativeLayout relLay = (RelativeLayout) this.findViewById(R.id.mainWindow);
for(int i = 1; i <= currQuantity; i++){
TextView tv=new TextView(this);
tv.setTextSize(40);
tv.setId(baseID + i);
tv.setPadding(24, 4, 24, 4);
tv.setBackgroundColor(0x110000FF);
tv.setText(String.valueOf(baseID + i)); //Val for debugging
tv.setTextColor(0xFFFFFFFF);
relLay.addView(tv);
}
baseID += currQuantity;
sortLayout();
}
Then the sorting:
public void sortLayout() {
int leftNum = 20;
int topNum = 0;
for(int i = 1; i <= baseID; i++){
TextView tv= (TextView) this.findViewById(baseID);
MarginLayoutParams mp = new MarginLayoutParams(tv.getLayoutParams());
mp.setMargins(leftNum, topNum, 0, 0);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(mp);
tv.setLayoutParams(lp);
leftNum += distStep;
if(leftNum >= distStep * numCols){
leftNum = leftPad;
topNum += distStep;
}
}
}
What I am getting is all the textViews pile up in the top left corner, except the last one which is positioned exactly where it should be. So it seems in my head, the params object isn't applying until the loop ends or something.. but logically I don't see why.
As I said, this worked when I set the params at the get go, problem is mass updating them all at once. I am pretty new to android, so I hope I'm not just doing something stupid.
Thanks for your time
Margin means it will set a gap between the previous view and current view.
When you add view1, view2 and view3 to grid layout and if you remove view2 at some point of time, then the margin for view3 is set according to view1. So, it won't leave empty space in place of view2. Instead of removing view2 at run time, set the background for view2 as null and set the text as empty as below.
textView.setBackground(null);
textView.setText("");
So that the view is still available but looks as deleted.
Started looking into GridView using an extended baseAdapter. Looks promising:
For more (see #2):
http://www.mkyong.com/android/android-gridview-example/
I get an error when i try to use the a recycled gridview every time if convertView != null then i get an error here is my source code.
it will give me an error right at text = (TextView) convertView; in the else statment. I am really lost here, I would just stop recycling the views but then its to heavy on memory and its choppy scrolling
$ here is the imageadapter.java
public View getView(int position, View convertView, ViewGroup parent) {
RelativeLayout lay;
ImageView image;
TextView text;
if (convertView == null) {
Log.d("height", "Width = " + width);
lay = new RelativeLayout(mContext);
image = new ImageView(mContext);
text = new TextView(mContext);
//text.setText("This is a test");
text.setTextSize(14);
text.setTextColor(Color.WHITE);
text.setGravity(Gravity.LEFT | Gravity.TOP);
text.setPadding(2, 2, 2, 2);
text.setBackgroundColor(Color.parseColor("#80000000"));
RelativeLayout.LayoutParams textLayout = new RelativeLayout.LayoutParams(
(int) Math.round(width / 2.0),
(int) Math.round(width / 8.3));
textLayout.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
text.setLayoutParams(textLayout);
MarginLayoutParams textMarginFix = (ViewGroup.MarginLayoutParams) text
.getLayoutParams();
textMarginFix.setMargins(0, 0, 0, (int) Math.round(width / 45.0));
text.setLayoutParams(textMarginFix);
image.setLayoutParams(new LayoutParams((int) Math
.round(width / 2.0), (int) Math.round(width / 2.0)));
image.setScaleType(ImageView.ScaleType.CENTER_CROP);
//image.setImageResource(mThumbIds[position]);
lay.setLayoutParams(new GridView.LayoutParams((int) Math
.round(width / 2.0), (int) Math.round(width / 2.0)));
lay.setBackgroundResource(R.drawable.shadowimage);
lay.setPadding(5, 5, 15, 15);
//lay.setId(mThumbIds[position]);
//lay.addView(image);
//lay.addView(text);
}
else
{
text = (TextView) convertView;
image = (ImageView) convertView;
lay = (RelativeLayout) convertView;
}
image.setImageResource(mThumbIds[position]);
text.setText("This is a test");
lay.addView(image);
lay.addView(text);
return lay;
}
$here is where i call the imageadapter from another class
#Override
public Object instantiateItem(View container, int position) {
View contentView;
switch (position) {
case 0:
LayoutInflater mInflater = LayoutInflater.from(mContext);
View contentView = mInflater.inflate(R.layout.image_grid_view, null);
Display display = mContext.getWindowManager().getDefaultDisplay();
final int width = display.getWidth();
int height = display.getHeight();
float scale = mContext.getResources().getDisplayMetrics().density;
GridView gridview = (GridView) contentView.findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(mContext, width, height, scale));
gridview.setFocusable(true);
gridview.requestFocus();
gridview.setOnItemClickListener(itemClickListener);
((ViewPager) container).addView(contentView, 0);
break;
...return contentView
convertView is the view that entirely represents one item in your GridView. If that is a TextView, it will be a TextView, if it is an entire layout, you will receive the entire layout and so on.
So how do you know and define what is "the view that represents one item"? Simple, it is whatever you create when convertView == null and then return from getView.
Simply you are receiving a used item and you are just modifying it to update it to the appropriate content. So you should utilize type casting to get this View you receive in a format you want.
Code like below will get you what you want without redoing things you don't need to do (aka you do not need to re-add child Views from a convertView, only a new view):
public View getView(int position, View convertView, ViewGroup parent) {
RelativeLayout lay;
ImageView image;
TextView text;
if (convertView == null) {
// Setup your 'item view'
lay = new RelativeLayout(mContext);
image = new ImageView(mContext);
text = new TextView(mContext);
// Do all your customizing stuff (aka size, color, format, padding layout params)
lay.addView(image, 0);
lay.addView(text, 1);
} else {
lay = (RelativeLayout) convertView;
image = (ImageView) lay.getChildAt(0);
text = (TextView) lay.getChildAt(1);
}
// Set content for your image and text
return lay;
}
[ADDITION]
Further, you have the code
image.setImageResource(mThumbIds[position]);
text.setText("This is a test");
lay.addView(image);
lay.addView(text);
return lay;
outside the if and the else, what this means is that you are trying to add a subview EVERY TIME a cell's view is asked for. You really only need to add views to lay within the if portion of your routine.
[ORIGINAL]
Most likely convertView is your parent, and all other views are sub to it. In your else clause, all you do is set each one to the SAME EXACT THING. How can the convertView be three completely different things all at once.
Most likely it needs to be:
text = (TextView) convertView.SomeTextViewSubToConvertView;
image = (ImageView) convertView.SomeImageViewSubToConvertView;
lay = (RelativeLayout) convertView.SomeRelativeLayoutSubToConvertView;
Can anybody tell me how to align tab text in the center in android? I had given android:gravity="center" for LinearLayout and TabWidget. It is still not working. Can anybody tell me how to do this?
Thanks
use this
int tabCount = tabHost.getTabWidget().getTabCount();
for (int i = 0; i < tabCount; i++) {
final View view = tabHost.getTabWidget().getChildTabViewAt(i);
if ( view != null ) {
// reduce height of the tab
view.getLayoutParams().height *= 0.66;
// get title text view
final View textView = view.findViewById(android.R.id.title);
if ( textView instanceof TextView ) {
// just in case check the type
// center text
((TextView) textView).setGravity(Gravity.CENTER);
// wrap text
((TextView) textView).setSingleLine(false);
// explicitly set layout parameters
textView.getLayoutParams().height = ViewGroup.LayoutParams.FILL_PARENT;
textView.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT;
}
}
}
Use android:layout_gravity="center"