Setting row height in a ListView - android

I'm trying to programatically set the height of rows in a ListView based off of some scaling factor. I've been looking around the internet for hours and cannot figure out why my code doesn't work.
UPDATE
Actually more things with the layout are having problems than just the height. The layout_weight in the XML file for all the TextViews doesn't do anything at all. Setting the textSize on the TextViews programatically doesn't work either, the text is bigger than I set it. But setting visibility on the TextViews works perfectly fine as well as setting the text. Another thing to mention is that the only thing I can think of that separates this from any normal situation in which this code would work is that I'm putting this ListView in a custom ViewGroup.
Here's my adapter code for getView() where I'm trying to set the height.
public View getView(int position, View convertView, ViewGroup parent) {
View layout = convertView;
if (layout == null) {
LayoutInflater inflater = activity.getLayoutInflater();
layout = inflater.inflate(R.layout.listview_row_parameter, parent, false);
}
int rowHeight = (int) (defaultRowHeight * scale);
layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, rowHeight));
layout.requestLayout();
Parameter p = getItem(position);
TextView tvName = (TextView) layout.findViewById(R.id.tvName);
TextView tvValue = (TextView) layout.findViewById(R.id.tvValue);
TextView tvMin = (TextView) layout.findViewById(R.id.tvMin);
TextView tvMax = (TextView) layout.findViewById(R.id.tvMax);
TextView tvAvg = (TextView) layout.findViewById(R.id.tvAvg);
if (showName) {
tvName.setVisibility(View.VISIBLE);
tvName.setTextSize(defaultTextSize * scale);
tvName.setText(p.getName());
} else {
tvName.setVisibility(View.GONE);
}
if (showValue) {
tvValue.setVisibility(View.VISIBLE);
tvValue.setTextSize(defaultTextSize * scale);
tvValue.setText(formatValue(p.getCurrentValue().value, p));
} else {
tvValue.setVisibility(View.GONE);
}
if (showMin) {
tvMin.setVisibility(View.VISIBLE);
tvMin.setTextSize(defaultTextSize * scale);
tvMin.setText(formatValue(p.getMinValue().value, p));
} else {
tvMin.setVisibility(View.GONE);
}
if (showMax) {
tvMax.setVisibility(View.VISIBLE);
tvMax.setTextSize(defaultTextSize * scale);
tvMax.setText(formatValue(p.getMaxValue().value, p));
} else {
tvMax.setVisibility(View.GONE);
}
if (showAvg) {
tvAvg.setVisibility(View.VISIBLE);
tvAvg.setTextSize(defaultTextSize * scale);
tvAvg.setText(formatValue(p.getAverage(), p));
} else {
tvAvg.setVisibility(View.GONE);
}
return layout;
}
And here's my XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<TextView
android:id="#+id/tvName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:textColor="#android:color/white"
android:singleLine="true" />
<!-- More TextViews here -->
The rows all show up just fine with the expected content, but the height isn't correct.

Related

Resizing ListView Rows Dynamically

Overview:
I have a ListView of different types of rows including images and text of varying heights. At runtime, I am trying to dynamically set the heights of the layout containing the image based on the width of the row. So the row's width is set to match_parent (because we want it to fill the width of the device), but the height must be calculated at runtime to get a specific aspect ratio for the frame.
Here's the code snippet from the Adapter that I'm using:
#Override
public View getView(View convertView) {
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(
R.layout.chat_row_image, null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
ViewTreeObserver observer = holder.videoFrame.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
// TODO Auto-generated method stub
frameWidth = holder.container.getWidth();
int width = frameWidth;
int height = (int) (frameWidth / Utilities.MEDIA_CELL_ASPECT_RATIO);
Log.d(TAG, "Calculated : " + width + "," + height);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(width, height);
holder.messageImage.setLayoutParams(params);
holder.videoFrame.getViewTreeObserver().removeGlobalOnLayoutListener(
this);
Log.d(TAG, "Imageview : " + holder.messageImage.getWidth() + "," + holder.messageImage.getHeight());
}
});
return convertView;
}
The problem: this code works well but during scrolling through the ListView, there are UI glitches that are readily noticeable. The main UI bug is that the rows have a pre-defined height from the XML file and are instantly transitioning to the new height we've calculated once the image finishes loading. This causes the entirety of contents below that row to suddenly shift as soon as the row appears on the screen. Also, we're scrolling from the bottom to the top (this is a chat thread).
Things I've tried:
We tried scrolling through the entire ListView via "setSelection" method (from ListView) to "preload" the contents before the user sees them. That didn't work and it doesn't seem like the images are loaded during the brief time we're scrolling past them.
We've tried setting a static XML file width and height, and that fixes the issue, but doesn't account for different screen sizes.
What I need help with: We want to keep the scrolling smooth even while resizing the layout dynamically. The final resort would be to create different XML files for each screen size category and hard code the height, but that would not keep our frame's aspect ratio as we desire.
Please let me know if there are any clarifications you would want. Thanks in advance!
The answer was to set the dimensions of the frame in the constructor of the Adapter instead of the getView() method. Based on Nannuo Lei's suggestion, we are not using the ViewTreeObserver.OnGlobalLayoutListener(), instead we are calculating the dimensions of the frame based on the display's width and padding/margin of other layout elements.
public ImageChatRow(Context context) {
this.mContext = context;
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
displayWidth = size.x - 40; //padding is 40 in our case
displayHeight = (int) (displayWidth / Utilities.MEDIA_CELL_ASPECT_RATIO);
}
Then in the getView() method, we just set the dimensions of the frame directly after inflating the view.
public View getView(View convertView) {
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(
R.layout.chat_row, null);
holder = new ViewHolder(convertView);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(displayWidth, displayHeight);
layoutParams.gravity = Gravity.CENTER;
holder.frame.setLayoutParams(layoutParams);
convertView.setTag(holder);
} else
holder = (ViewHolder) convertView.getTag();
This solves the problems of the glitches in loading rows and dynamically setting their heights. We haven't observed any jumpiness in the ScrollView since implementing this code!
You can add a LinearLayout outside in chat_row_image.xml, like this
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/layout_ll
android:layout_width="wrap_content"
android:layout_height="wrap_content">
[...]
</LinearLayout>
</RelativeLayout>
In Adapter.java
#Override
public View getView(View convertView) {
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(
R.layout.chat_row_image, null);
holder = new ViewHolder(convertView);
LinearLayout ll = (LinearLayout) view.findViewById(R.id.layout_ll);
LayoutParams linearParams = (LayoutParams) ll.getLayoutParams();
linearParams.width = width;
linearParams.height = height;
ll.setLayoutParams(linearParams);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
return convertView;
}

Why does the text in ListView item disappear when scrolling?

I have ListView which contains items containing a View and a TextView:
chat_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="90dp"
android:id="#+id/chat_message_wrapper"
xmlns:pixlui="http://schemas.android.com/apk/com.neopixl.pixlui">
<View
android:id="#+id/message_indicator"
android:layout_width="10dp"
android:layout_height="90dp"/>
<com.neopixl.pixlui.components.textview.TextView
android:id="#+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/midnight_blue"
android:padding="14dp"
android:layout_centerVertical="true"/>
</RelativeLayout>
And this is getView() in my Adapter class:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.chat_item, null);
}
ChatMessageItem item = getItem(position);
if(item != null) {
TextView messageTextView = (TextView) view.findViewById(R.id.message);
ViewGroup messageWrapper = (ViewGroup) view.findViewById(R.id.chat_message_wrapper);
View messageIndicatorView = view.findViewById(R.id.message_indicator);
if(messageTextView != null) {
messageTextView.setText(String.valueOf(item.getMessage()));
RelativeLayout.LayoutParams textParams = (RelativeLayout.LayoutParams)messageTextView.getLayoutParams();
RelativeLayout.LayoutParams indicatorParams = new RelativeLayout.LayoutParams(10, ViewGroup.LayoutParams.MATCH_PARENT);
RelativeLayout.LayoutParams messageWrapperParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 90);
if(item.getSender() == ChatMessageItem.Sender.ME) {
textParams.addRule(RelativeLayout.LEFT_OF, R.id.message_indicator);
indicatorParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
messageIndicatorView.setBackgroundColor(getContext().getResources().getColor(R.color.light_blue));
}
else if(item.getSender() == ChatMessageItem.Sender.OTHER) {
textParams.addRule(RelativeLayout.RIGHT_OF, R.id.message);
indicatorParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
messageIndicatorView.setBackgroundColor(getContext().getResources().getColor(R.color.silver));
}
messageTextView.setLayoutParams(textParams);
messageIndicatorView.setLayoutParams(indicatorParams);
messageWrapper.setLayoutParams(messageWrapperParams);
}
}
return view;
}
I added the following line to at least keep the height of the items constant, which used to also change (which will probably give me problems later, as the content is dynamic, but ok..)
RelativeLayout.LayoutParams messageWrapperParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 90);
The problem is when I scroll up and down more and more text disappears. messageIndicatorView does not disappear though, only the text disappears. If I keep scrolling enough, all text will disappear. What am I doing wrong and how can I fix it? Thanks. (I know I must use a ViewHolder for better performance, but I will do that when this problem is fixed)
The problem is that as the ListView recycles and reuses the views, conflicting rules are added to the RelativeLayout.LayoutParams instances for the #id/message TextView. In particular this happens whenever a view for a "ME" message is reused for an "OTHER" message, or vice-versa.
RelativeLayout.LayoutParams keeps a list of rules (actually an array by verb, so that you cannot add, say, two LEFT_OF rules -- but any other combination is possible, including problematic ones).
The easiest solution is to use a new RelativeLayout.LayoutParams object each time, by changing this line:
RelativeLayout.LayoutParams textParams =
(RelativeLayout.LayoutParams)messageTextView.getLayoutParams();
into:
RelativeLayout.LayoutParams textParams =
new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
There are other solutions, such as having different actual layouts for each kind of ListView item (via getItemViewType()) but it's probably overkill in this case. However if the differences between the two kinds of views were greater, it might be worth considering.

Image resets to default after scrolling - Android Custom View

So I've been creating a custom view similar to GridView. It loads and scrolls through images just fine when they are resources inside the app but now that I'm using images coming in through an HTTP request, the images aren't loading correctly.
When the app starts: all images are set to the default (bad)
After scrolling past that cell and immediately scrolling back to it: image loads correctly (good)
After scrolling back to that same cell sometime later: image was set back to the default (bad)
Does anyone have any ideas of what could be causing this error? I assume it's some kind of recycling issue but I haven't been able to fix it.
Here is my xml file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:paddingBottom="1dip"
android:background="#color/white"
android:id="#+id/highlight_counter_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:gravity="center" >
<ImageView
android:id="#+id/catalog_image"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<View
android:id="#+id/solid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#android:color/black" />
<View
android:id="#+id/text_gradient"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#id/solid"
android:background="#drawable/highlight_text_gradient" />
<TextView
android:id="#+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:padding="#dimen/highlight_text_padding"
android:ellipsize="end"
android:gravity="bottom"
android:maxLines="2"
android:textColor="#color/white"
android:textSize="#dimen/text_large" />
</RelativeLayout>
Here is an excerpt from my adapter (where I think the problem probably lies):
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final LayoutParams lp;
int viewType = getItemViewType(position);
ImageView img;
PulseTextView title;
Resources res = getContext().getResources();
int height = (int) res.getDimension(R.dimen.icon_main_size);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext.get().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.element_item, parent, false)
LayoutParams layp = new LayoutParams(height);
convertView.setLayoutParams(layp);
}
img = ViewHolder.get(convertView,R.id.catalog_image);
title = ViewHolder.get(convertView,R.id.title);
final CatalogItem channel = getCatalogItem(position);
// find the url of the associated image then set image
String url = null;
try {
url = mCatalogHandler.getImageUrl(CatalogHandler.VALUE_ICON, channel.mPrimaryKey, 100, 100);
} catch (CatalogException e) {
e.printStackTrace();
}
if (url == null || TextUtils.isEmpty(url) || url.equals("null")) {
img.setImageBitmap(mDefaultPic);
} else {
// downloads the image to img
mImageDownloader.download(url, img, mDefaultPic, false);
}
title.setText(channel.mDomain);
img.setScaleType(ScaleType.FIT_XY);
img.setTag(RAMImageCache.KEY_URL, url);
// set the gradient behind the text
View grad = convertView.findViewById(R.id.text_gradient);
ViewUtils.setHeight(grad, height * 3 / 5);
grad.getBackground().setDither(true);
View solid = convertView.findViewById(R.id.solid);
ViewUtils.setHeight(solid, height / 5);
// set the padding based on the position on the screen
DisplayMetrics displaymetrics = new DisplayMetrics();
((Activity)getContext()).getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int width = displaymetrics.widthPixels;
if (convertView.getRight() == width && convertView.getLeft() == 0) {
convertView.setPadding(0, 0, 0, 1);
} else if (convertView.getRight() == width) {
//convertView.setPadding(1, 0, 0, 1);
convertView.setPadding(0, 0, 1, 1);
} else if (convertView.getLeft() == 0) {
//convertView.setPadding(0, 0, 1, 1);
convertView.setPadding(1, 0, 0, 1);
}
// set the onclicklistener to jump to the next fragment
convertView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
Bundle bundle = new Bundle();
bundle.putString("channelitem", channel.getMetadata().toString());
ChannelFragment fragment = new ChannelFragment();
fragment.setArguments(bundle);
((PulseFragmentActivity)mContext.get()).openFragment(fragment);
}
});
return convertView;
}
static class ViewHolder {
ImageView img;
TextView title;
public ViewHolder(ImageView i, PulseTextView t) {
img = i;
title = t;
}
public static <T extends View> T get(View view, int id) {
SparseArray<View> viewHolder = (SparseArray<View>) view.getTag();
if (viewHolder == null) {
viewHolder = new SparseArray<View>();
view.setTag(viewHolder);
}
View childView = viewHolder.get(id);
if (childView == null) {
childView = view.findViewById(id);
viewHolder.put(id, childView);
}
return (T) childView;
}
}
Any point in the right direction would help greatly! Let me know if there are any other code snippets you would need to see.
I suggest one way to debug is to try another image download library to find out if the error is in your code. I used https://github.com/koush/UrlImageViewHelper and it works well when cell is reused, and its API is similar to what you used now
The behaviour very much depends on what and how does your mImageDownloader handles the downloaded image.
In most cases LRU Cache implementation might be used to store your downloaded image and this cache has a maximum value of bytes assigned. Once your cached image exceeded this value, the old bitmaps will be discarded, hence why you are seeing default image and you need to re-download it.
My suggestion is after you have downloaded the image, scale it as small as you can, so that you can cache as much bitmaps as you could.
There is no way Android could cache up all your downloaded images due to memory restriction.

Adding space between columns of a TableLayout

I have a TableLayout where I add dynamically TableRows. In each TableRow, I add a Button.
I just would like to add some space between my columns (which are my buttons) but I can't figure out how...
I've tried to change all the possible margins but it doesn't work :(
So maybe I made a mistake in my code where I inflate them from XML files:
private void createButtons(final CategoryBean parentCategory) {
final List<CategoryBean> categoryList = parentCategory.getCategoryList();
title.setText(parentCategory.getTitle());
// TODO à revoir
int i = 0;
TableRow tr = null;
Set<TableRow> trList = new LinkedHashSet<TableRow>();
for (final CategoryBean category : categoryList) {
TextView button = (TextView) inflater.inflate(R.layout.button_table_row_category, null);
button.setText(category.getTitle());
if (i % 2 == 0) {
tr = (TableRow) inflater.inflate(R.layout.table_row_category, null);
tr.addView(button);
} else {
tr.addView(button);
}
trList.add(tr);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
CategoryBean firstChild = category.getCategoryList() != null && !category.getCategoryList().isEmpty() ? category
.getCategoryList().get(0) : null;
if (firstChild != null && firstChild instanceof QuestionsBean) {
Intent intent = new Intent(CategoryActivity.this, QuestionsActivity.class);
intent.putExtra(MainActivity.CATEGORY, category);
startActivityForResult(intent, VisiteActivity.QUESTION_LIST_RETURN_CODE);
} else {
Intent intent = new Intent(CategoryActivity.this, CategoryActivity.class);
intent.putExtra(MainActivity.CATEGORY, category);
startActivityForResult(intent, VisiteActivity.CATEGORY_RETURN_CODE);
}
}
});
i++;
}
for (TableRow tableRow : trList) {
categoryLaout.addView(tableRow);
}
}
My button_table_row_category.xml:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/buttonTableRowCategory"
style="#style/ButtonsTableRowCategory"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="#string/validate" />
My table_row_category.xml:
<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tableRowCategory"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="100dp"
android:gravity="center"
android:padding="5dp" >
</TableRow>
Thank you for your help.
In the case of a TableLayout, Buttons themselves are the columns. That means you have to advise the Buttons to keep some space inbetween. You can do this by using layout parameters. They are much easier to set in XML, but it also works programmatically. It's important that you always use the LayoutParam class of the parent layout of the element where you apply it - in this case the parent is a TableRow:
// Within createButtons():
android.widget.TableRow.LayoutParams p = new android.widget.TableRow.LayoutParams();
p.rightMargin = DisplayHelper.dpToPixel(10, getContext()); // right-margin = 10dp
button.setLayoutParams(p);
// DisplayHelper:
private static Float scale;
public static int dpToPixel(int dp, Context context) {
if (scale == null)
scale = context.getResources().getDisplayMetrics().density;
return (int) ((float) dp * scale);
}
Most dimension attributes in Android take pixels if you set them programmatically - therefore you should use something like my dpToPixel() method. Please, don't EVER use pixel values in Android! You will regret it later on.
If you don't want the rightmost button to have this margin, just check with an IF and don't add the LayoutParam on it.
Solution in XML:
To avoid the LayoutInflater erasing your XML-defined attributes, do this while inflating (taken from Layout params of loaded view are ignored):
View view = inflater.inflate( R.layout.item /* resource id */,
MyView.this /* parent */,
false /*attachToRoot*/);
Alternative: Use a GridView like so: Android: Simple GridView that displays text in the grids
Add Padding Right for a component in the table row component
<TableRow
android:id="#+id/tableRow1">
<TextView
android:id="#+id/textView1"
android:paddingRight="20dp" />
</TableRow>
Try android:layout_marginRight="6dp" this worked for me.
Try Using the setColumnStretchable function of the TableLayout. Give it a columnn index and set its stretchable property to true.
Eg. If you have 3 columns.
TableLayout tblLayout;
tblLayout.setColumnStretchable(0, true);
tblLayout.setColumnStretchable(1, true);
tblLayout.setColumnStretchable(2, true);
The above will give you equal spacing between all 3 columns of the tableLayout.

implementing setOnClickListener

i have this sample and i am trying to Implement a Click on item(s) inside sub view
i have this two xml files
this is the subview.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="#+id/textLabel"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:textSize="50dip"
android:textColor="#00FF00"
android:textStyle="bold"/>
</LinearLayout>
this is the scrollview.xml view:
<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="none">
<LinearLayout
android:layout_width="fill_parent"
android:id="#+id/scrollviewlinearlayout"
android:layout_height="fill_parent">
</LinearLayout>
</HorizontalScrollView>
and this is the Activity:
public class TestTwo extends Activity {
Context mContext;
HorizontalScrollView mScrollView;
LinearLayout mLinearLayout;
LinearLayout.LayoutParams mLinearLayoutParams;
Display mDisplay;
// scroll behaviour
private int mScrollStartPosition;
private static final float SCROLL_MARGIN = 0.2f;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
// load layout from xml and get references to sub-views
setContentView(R.layout.scrollview);
mScrollView = (HorizontalScrollView) findViewById(R.id.scrollview);
mLinearLayout = (LinearLayout) findViewById(R.id.scrollviewlinearlayout);
// get a display reference (used to find screen size)
mDisplay = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
// get the layout parameters to apply to the sub-views
mLinearLayoutParams = new LayoutParams(mDisplay.getWidth(), mDisplay.getHeight());
// add some views to the ScrollView
addViewsToScrollView();
}
private void addViewsToScrollView() {
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
for (int i = 0; i < 3; i++) {
// inflate view from xml
View child = inflater.inflate(R.layout.subview, null);
// give it a number
final TextView text = (TextView) child.findViewById(R.id.textLabel);
text.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
text.setText("Test");
}
});
text.setText("" + (i + 1));
// give it a colour
text.setBackgroundColor(Color.rgb((int) (Math.random() * 255), (int) (Math.random() * 255),
(int) (Math.random() * 255)));
// apply layout parameters, and add it
child.setLayoutParams(mLinearLayoutParams);
mLinearLayout.addView(child);
}
}
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
int viewWidth = mDisplay.getWidth(); // width of each view
int triggerWidth = (int) (SCROLL_MARGIN * viewWidth); // amount user has to scroll to move to next view
int pos = mScrollView.getScrollX();
int diff = pos % viewWidth; // offset of current scroll from leftmost view's snap position
int posLeftView = pos - diff; // absolute snap position of the leftmost view on screen
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
// Record the starting scroll position. This is used to decide the scroll direction.
mScrollStartPosition = pos;
break;
case MotionEvent.ACTION_UP:
if (pos > mScrollStartPosition) {
// Scrolling right
if (diff > triggerWidth) mScrollView.smoothScrollTo(posLeftView + viewWidth, 0);
else mScrollView.smoothScrollTo(posLeftView, 0);
} else {
// Scrolling left
if (diff > (viewWidth - triggerWidth)) mScrollView.smoothScrollTo(posLeftView + viewWidth, 0);
else mScrollView.smoothScrollTo(posLeftView, 0);
}
// replacing our scrollTo command with it's own
return true;
}
return super.dispatchTouchEvent(ev);
}
}
i tried to debug it and it seems its not fire the onClick event
can you help me please with this problem ?
You're doing a bunch of wild things that I'll leave for another time. Try text.setClickable(true) on your final TextView text
Ok sorry for all these edits. here are your problems though.
you shouldn't use the child statement
2. you shouldn't be setting an onclick listener for an item thats not within the current content
So......
final TextView text = (TextView) child.findViewById(R.id.textLabel);
should be
final TextView text = (TextView) findViewById(R.id.textLabel);
since the content needs to be set to the proper xml file
setContentView(R.layout.scrollview);
would need to be
setContentView(R.layout.<NAME OF SECOND XML FILE WHICH U DIDNT INCLUDE>);

Categories

Resources