While scrolling the gallery last item is scrolled and stops at left margin. I want to stop the last item at right margin of the screen. i am showing 3 items at a time on screen thanks for any suggestions.
public View getView(int position, View convertView, ViewGroup parent) {
Gallery newArticleRow;
LinearLayout layout = (LinearLayout) convertView;
if (layout == null) {
Log.d("in home", "HomeActivityListViewAdapter--- new getView:" + position);
// Inflate the news article row
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.news_articles_row, null);
newArticleRow = (Gallery) convertView
.findViewById(R.id.news_articles_gallery);
DisplayMetrics metrics = new DisplayMetrics();
FishwrapHomeActivity.this.getWindowManager().getDefaultDisplay()
.getMetrics(metrics);
MarginLayoutParams mlp = (MarginLayoutParams) newArticleRow
.getLayoutParams();
mlp.setMargins(-(metrics.widthPixels - (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 90, FishwrapHomeActivity.this
.getResources().getDisplayMetrics())), mlp.topMargin,
mlp.rightMargin, mlp.bottomMargin);
newArticleRow.setId(position);
newArticleRow.setLayoutParams(mlp);
convertView.setTag(newArticleRow);
convertView.setBackgroundColor(Color.WHITE);
convertView.setFocusableInTouchMode(false);
} else {
Log.d("in home", "HomeActivityListViewAdapter--- old getView:" + position);
// Get the newArticleRow HorizontialListView
newArticleRow = (Gallery) convertView.getTag();
}
// Set the adapter only if the ArticleRow
if (newArticleRow.getAdapter() == null || newArticleRow.getAdapter() != rowAdapters.get(position)) {
newArticleRow.setAdapter(rowAdapters.get(position));
newArticleRow.setOnItemClickListener(itemListener);
}
// Debug.stopMethodTracing();
return convertView;
}
#Rekha i think you should stop further scrolling functionality in that direction when position = lastitem - 1 element. You might want to do that through your Gallery instance ( gallery.getSelectedItemPosition() ) and the onscrollistener.
by the way, does this solve your previous "position restarts gallery in listview" issue? i have a similar issue that repeats my gallerys within my list when using a gallery holder.
Related
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;
}
I have a very strange problem in my navigation drawer.
I want to implement the navigation drawer like the one the Google Play Store has.
I've implement my navigation drawer in a base adapter but when I run my app in a emulator everythings looks fine when I open the navigation drawer, but when I click a item suddenly all items are mixed up(only on my android 2.3 device) The other one i;ve tested is a 4.4.2 Android device and everything works fine!
Code
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(ActionBarActivity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.drawer_list_item, null);
}
if (convertView != null) {
//i//f(!(navDrawerItems.get(position).IsLoaded())) {
//navDrawerItems.get(position).SetLoaded();
ImageView imgIcon = (ImageView) convertView.findViewById(R.id.icon);
TextView txtTitle = (TextView) convertView.findViewById(R.id.title);
TextView txtCount = (TextView) convertView.findViewById(R.id.counter);
if (navDrawerItems.get(position).getIconVisibility()) {
imgIcon.setImageResource(navDrawerItems.get(position).getIcon());
txtTitle.setTextSize(20);
//txtTitle.setMinHeight(20);
LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
llp.setMargins(8, 0, 0, 0); // llp.setMargins(left, top, right, bottom);
llp.height = 60;
txtTitle.setLayoutParams(llp);
convertView.setBackgroundResource(R.drawable.nav_little_border);
} else {
imgIcon.setVisibility(View.GONE);
}
txtTitle.setText(navDrawerItems.get(position).getTitle());
// displaying count
// check whether it set visible or not
if (navDrawerItems.get(position).getCounterVisibility()) {
txtCount.setText(navDrawerItems.get(position).getCount());
} else {
// hide the counter view
txtCount.setVisibility(View.GONE);
}
// }
}
I only want to show the icons for the last 2 items like (http://www.androidcentral.com/sites/androidcentral.com/files/styles/large_wm_brw/public/article_images/2014/04/Play-Movies-TV-sidebar.jpg?itok=qLSLoPNp)
this is the code in my custom adapter (THE CODE IN BROWN COLOR) when initially list is build proper margin is applied to valid items when i scroll down and again scroll up all the rows in list shifts the margin left by 20 what i'm doing wrong please reply soon
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
// getting data
final ViewMovieDetailsModel_ViewComments movies = getItem(position);
if (convertView == null)
{
convertView = View.inflate(context, R.layout.comment_row, null);
holder = new ViewHolder();
//getting handles
holder.comments_linearLayout = (LinearLayout) convertView.findViewById(R.id.comments_linearLayout);
holder.commenter_textView = (TextView) convertView.findViewById(R.id.comment_row_commenter);
holder.commented_on_textView = (TextView) convertView.findViewById(R.id.comment_row_comment_time);
holder.comment_text_textView = (TextView) convertView.findViewById(R.id.comment_row_comment_text);
holder.reply_button = (Button) convertView.findViewById(R.id.comment_row_reply_button);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder)convertView.getTag();
}
if (movies != null)
{
if (((movies.getParent_comment_id()).toString().equals("null")) && session.isLoggedIn()==true) {
holder.reply_button.setVisibility(View.VISIBLE);
}else{
holder.reply_button.setVisibility(View.INVISIBLE);
}
`if (!((movies.getParent_comment_id()).toString().equals("null")))
{
LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);
params.setMargins(20, 0, 0, 0);
holder.comments_linearLayout.setLayoutParams(params);
}`
holder.commenter_textView.setText(movies.getUsername_commentor());
holder.commenter_textView.setTag(movies.getUser_id_commentor());
return convertView;
}
because you are setting margins (the brown font) in 'if' statement:
if (movies != null)
just take it out of this if block (for example put it just before the return point)
Right now this code is probably not executed at the first view load, since the movie is null. When the getView is called second time, the movie is not null, and the marigin is set according to your 'brown' code.
if this is not the solution - maybe the inside if statement condition is not true (the one that is in first 'brown' row). so.. your own logic prevents the marigins to be set as you want :)
Please let me know if it helps.
One way you could go about solving this problem is instead of using LayoutParams.setMargins(20, 0, 0, 0), you could create an empty TextView whose width is 20 dp by default and whose position will be to the left of your rows contents. It will be View.GONE by default, but when if (!((movies.getParent_comment_id()).toString().equals("null"))) happens, you can set that to View.VISIBLE
I have a gridview that has multi items (buttons) I bind background for each item in my adapter
public View getView(int position, View convertView, ViewGroup parent) {
Button btn;
if (convertView == null)
{ // if it's not recycled, initialize some attributes
btn = new Button(mContext);
KeypadButton keypadButton = mButtons[position];
btn.setTag(keypadButton);
btn.setBackgroundResource(R.drawable.button_image);
btn.setTextColor(android.R.color.white);
}
else
{
btn = (Button) convertView;
}
btn.setText(mButtons[position].GetContent());
return btn;
}
the imageview item change it's size when I setBackgroundResource , Is it way to avoid resizing for image view item .
You can set LayoutParams with fixed size to avoid resizing the view
LayoutParams params = new LayoutParams(width, height);
btn.setLayoutParams(params);
if you don't set LayoutParams the size will be affected by background resource size.
to get more information visit:
https://stackoverflow.com/a/6170160/1891878
I am trying to change gridView column number. I call setNumColumn() and invalidateViews() to update the view.
However, the grid's cell width will not change dynamically. I set the stretchMode="columnWidth", but it didn't work.
Problem Solved:
The child view in the grid view do not re-calculate its layout when the grid view changes the column on runtime.
In your BaseAdapter, you should call forceLayout() to calculate its layout.
#Override
public View getView(final int position, View convertView,
ViewGroup parent) {
if (null == convertView) {
convertView = mInflater.inflate(
R.layout.mnm_customer_user_thumbnail, null);
control.txtUserName = (TextView) convertView
.findViewById(R.id.mnmTxtStudentName);
control.image = (ImageView) convertView
.findViewById(R.id.mnmImageStudent);
control.imageCheckBox = (ImageView) convertView
.findViewById(R.id.mnmImageCheckBox);
control.mnmOuterBounder = (RelativeLayout) convertView
.findViewById(R.id.mnmOuterBound);
convertView.setTag(control);
} else {
convertView.forceLayout();
}
...
...
...
...
Thanks
May be you could get help through this nice sample offered by Google
http://developer.android.com/shareables/training/BitmapFun.zip
The following code which locate in the ImageGridFragment.java is used to handle column number change dynamically during runtime such as screen orientation change when rotate the device:
Here is the comments:This listener is used to get the final width of the GridView and then calculate the number of columns and the width of each column. The width of each column is variable as the GridView has stretchMode=columnWidth. The column width is used to set the height of each view so we get nic square thumbnails.
mGridView.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (mAdapter.getNumColumns() == 0) {
final int numColumns = (int) Math.floor(
mGridView.getWidth() / (mImageThumbSize + mImageThumbSpacing));
if (numColumns > 0) {
final int columnWidth =
(mGridView.getWidth() / numColumns) - mImageThumbSpacing;
mAdapter.setNumColumns(numColumns);
mAdapter.setItemHeight(columnWidth);
if (BuildConfig.DEBUG) {
Log.d(TAG, "onCreateView - numColumns set to " + numColumns);
}
}
}
}
});
return v;
in xml u have to provide this attribute..
android:stretchMode="columnWidth" . In your adapter depending on the size(by `getCount()`) of the list colomn will create dynamically..