GridView numColumns=auto_fit, prevent items from being stretched - android

I would like to display items in a dialog. I used GridView. If I don't set the column width manually, GridView used hard-coded column number 2 like figure 1. If I set the column width, then it showed as many columns as possible like figure 2.
The problem is GridView seems to stretch the item to fill the whole screen, when I set a hard-coded width for the item (refer the code below). What can I prevent this? My final destination is to remove the red area in Figure 2. That should shrink the dialogue width by the amount of the red areas.
Figure 1.
Figure 2.
my_dialogue.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TableRow>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Family"/>
<GridView
android:stretchMode="columnWidth"
android:horizontalSpacing="0dp"
android:numColumns="auto_fit"
android:id="#+id/familyGrid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</TableRow>
</TableLayout>
my_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:background="#android:color/holo_red_dark"
android:layout_height="wrap_content">
<ImageView
android:background="#android:color/holo_blue_dark"
android:layout_width="48sp"
android:layout_height="48sp"/>
<TextView
tools:text="Some application"
android:id="#+id/tvLabel"
android:background="#android:color/holo_blue_bright"
android:gravity="center_vertical"
android:layout_width="192sp"
android:layout_height="48sp"/>
</LinearLayout>
MyDialogue.java
package com.example.me.test2;
import android.content.res.Resources;
import android.database.DataSetObserver;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatDialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridView;
import android.widget.ListAdapter;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import static android.util.TypedValue.COMPLEX_UNIT_SP;
import static android.util.TypedValue.applyDimension;
public class MyDialogue extends AppCompatDialogFragment
{
String TAG = this.getClass().getName();
private static MyDialogue instance;
private GridView myGrid;
public static MyDialogue getInstance()
{
if(instance == null)
{
instance = new MyDialogue();
}
return instance;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState)
{
setStyle(STYLE_NO_TITLE, 0);
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.my_dialogue, container, false);
myGrid = (GridView)v.findViewById(R.id.familyGrid);
//If I do not set the column width, it does not know the item width,
//and the column number falls back to 2.
Resources r = getResources();
float px = applyDimension(COMPLEX_UNIT_SP, 192+48, r.getDisplayMetrics());
myGrid.setColumnWidth((int)px);
ArrayList<String> list = new ArrayList<>();
list.add("Father: Homer Simpson");
list.add("Mother: Marge Simpson");
list.add("Son: Bart Simpson");
list.add("Daughter: Lisa Simpson");
list.add("Baby: Maggie Simpson");
list.add("Dog: Santa's L. Helper");
MyAdapter oa = new MyAdapter(list);
myGrid.setAdapter(oa);
return v;
}
class MyAdapter implements ListAdapter
{
List<String> list;
public MyAdapter(List<String> list)
{
this.list = list;
}
#Override
public boolean areAllItemsEnabled()
{
return true;
}
#Override
public boolean isEnabled(int position)
{
return true;
}
#Override
public void registerDataSetObserver(DataSetObserver observer)
{
}
#Override
public void unregisterDataSetObserver(DataSetObserver observer)
{
}
#Override
public int getCount()
{
return list.size();
}
#Override
public Object getItem(int position)
{
return list.get(position);
}
#Override
public long getItemId(int position)
{
return 0;
}
#Override
public boolean hasStableIds()
{
return false;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
View v = View.inflate(myGrid.getContext(), R.layout.my_item, null);
TextView tvLabel = (TextView) v.findViewById(R.id.tvLabel);
tvLabel.setText(list.get(position));
return v;
}
#Override
public int getItemViewType(int position)
{
return 0;
}
#Override
public int getViewTypeCount()
{
return 1;
}
#Override
public boolean isEmpty()
{
return list.isEmpty();
}
}
}
MainActivity.java
package com.example.me.test2;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.AppCompatDialogFragment;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity
{
String TAG = this.getClass().getName();
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnShow = (Button)findViewById(R.id.btnShow);
btnShow.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
FragmentManager manager = getSupportFragmentManager();
AppCompatDialogFragment dialogue = MyDialogue.getInstance();
dialogue.show(manager, "dialogue");
}
});
}
}

if i understood your question, you may want to put the gridView inside a linear layout, setting to grid view to fill the linear layout, but put some padding to the linear layout. good luck.

Related

ListFragment item selection doesn't always work when nested into ViewPager2

I have a ViewPager2, connected with a TabLayout, that creates multiple fragments, each composed of a ListFragment instance with a single item that can be selected (using android:choiceMode="singleChoice").
The problem is that when running on the Android Emulator (Pixel 2, API 28) after some clicking and scrolling the selection doesn't happen at all as if I didn't click. But if I attach the Android Studio Profiler I can see the red circle every time I click, even if the toast is not displayed and the item not marked as selected.
This is my full code, it's just a simple example.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<-- Tab layout sync-ed with ViewPager2 -->
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabs"
style="#style/Widget.MaterialComponents.TabLayout.Colored"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.google.android.material.appbar.AppBarLayout>
<!-- ViewPager2 to handle left/right scrolling too -->
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/tabviewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
l_v_page.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LVPageFragment">
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"
android:background="#color/white">
</ListView>
</FrameLayout>
l_v_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?android:attr/activatedBackgroundIndicator" >
<TextView
android:id="#+id/row_num"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginRight="4dp"
android:gravity="center"
android:minHeight="?android:attr/listPreferredItemHeightLarge"
android:textSize="30dp"
android:textStyle="bold" />
<TextView
android:id="#+id/row_descr"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="#id/row_num"
android:layout_alignBottom="#id/row_num"
android:layout_toRightOf="#id/row_num"
android:gravity="center_vertical"
android:textColorHighlight="#FFFFFF"
android:textSize="16sp" />
</RelativeLayout>
MainActivity.class
package com.example.testui4;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Lifecycle;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import android.os.Bundle;
import com.example.testui4.databinding.ActivityMainBinding;
import com.google.android.material.tabs.TabLayoutMediator;
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
// Create adapter for ViewPager2
binding.tabviewpager.setAdapter(new VPAdapter(this));
// Connect tabs with the ViewPager2
new TabLayoutMediator(binding.tabs, binding.tabviewpager, (tab, position) ->
{ tab.setText("List " + (position + 1)); }).attach();
setContentView(binding.getRoot());
}
#Override
protected void onDestroy() {
super.onDestroy();
binding = null;
}
// Inner class to handle ViewPager2 with 4 fixed pages
private class VPAdapter extends FragmentStateAdapter {
public VPAdapter(#NonNull FragmentActivity fragmentActivity) { super(fragmentActivity); }
public VPAdapter(#NonNull FragmentManager fragmentManager, #NonNull Lifecycle lifecycle) { super(fragmentManager, lifecycle); }
#NonNull
#Override
public Fragment createFragment(int position) { return LVPageFragment.newInstance(position); }
#Override
public int getItemCount() { return 4; }
}
}
LVAdapter.class
package com.example.testui4;
import android.content.Context;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class LVAdapter extends BaseAdapter {
protected final Context context;
protected SparseArray<String> mChoices = null;
public LVAdapter(Context ctx) { this.context = ctx; }
#Override
public boolean hasStableIds() {
return true;
}
#Override
public int getCount() {
if (mChoices != null)
return mChoices.size();
else
return 0;
}
#Override
public Object getItem(int i) {
if (mChoices != null)
return mChoices.get(i);
else
return null;
}
#Override
public long getItemId(int i) { return i; }
#Override
public View getView(int position, View convertView, ViewGroup parent) {
RelativeLayout row = (RelativeLayout) convertView;
if (row == null) {
// The view is not recycled, must be re-created
LayoutInflater inflater = (LayoutInflater) LayoutInflater.from(context);
row = (RelativeLayout) inflater.inflate(R.layout.l_v_item, parent, false);
}
// Get objects
TextView txtNum = (TextView) row.findViewById(R.id.row_num);
TextView txtDescr = (TextView) row.findViewById(R.id.row_descr);
// Set properties
txtNum.setText(Integer.toString(mChoices.keyAt(position)));
txtDescr.setText(mChoices.valueAt(position));
// Return the row
return row;
}
public void updateChoices(SparseArray<String> choices) {
this.mChoices = choices;
notifyDataSetChanged();
}
}
LVPageFragment.class
package com.example.testui4;
import android.os.Bundle;
import android.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.ListFragment;
import com.example.testui4.databinding.LVPageBinding;
public class LVPageFragment extends ListFragment {
private static final String ARG_NUMBER = "number";
private int mNumber = 1;
private LVPageBinding binding;
public LVPageFragment() { }
public static LVPageFragment newInstance(int number) {
LVPageFragment fragment = new LVPageFragment();
Bundle args = new Bundle();
args.putInt(ARG_NUMBER, number);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) { mNumber = getArguments().getInt(ARG_NUMBER); }
}
#Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
binding = LVPageBinding.inflate(inflater, container, false);
// List contents (may change in future for each fragment instance)
int intPage = mNumber + 1;
SparseArray<String> placeholder = new SparseArray<>();
placeholder.put(1, "ALPHA " + intPage);
placeholder.put(2, "BRAVO " + intPage);
placeholder.put(3, "CHARLIE " + intPage);
placeholder.put(4, "DELTA " + intPage);
placeholder.put(5, "FOXTROT " + intPage);
placeholder.put(6, "GOLF " + intPage);
placeholder.put(7, "HOTEL " + intPage);
placeholder.put(8, "INDIA " + intPage);
// Send data to the adapter and setup list fragment
LVAdapter adapter = new LVAdapter(getContext());
adapter.updateChoices(placeholder);
setListAdapter(adapter);
return binding.getRoot();
}
#Override
public void onListItemClick(#NonNull ListView l, #NonNull View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Toast.makeText(requireActivity(),"You clicked #" + (position + 1) + " on page #" + (mNumber + 1),
Toast.LENGTH_SHORT).show();
}
}
Result:
Why does that happen and how can I fix it?
EDIT: I tried to test the same app in a real device and there are no issues, so maybe it is a problem of the emulator?
There is a bug with the ViewPager2 and ListFragment: https://issuetracker.google.com/issues/256270071
I suppose it may or may not reproduce on real devices.
If having some predefined number of fragments this could be fixed calling pager.setOffscreenPageLimit with a value ≥ number of fragments.

CardView not inflating in RecyclerView

I cannot figure out why I can't see the CardView when I run the app. It shows in the design window in Android Studio, but when I run the app, there are no errors that come up, and the app functions normally, with the exception of the CardView not showing.
Before I post my code, here is what I've tried researching to see if I was making the same errors:
CardView not shown in RecyclerView
card view not showing up
(apparently, I need to have more than 10 reputation to post more than 2 links, just know there was about 10)
Please know that I'm relatively new to development and RecyclerView and that I really did try my best to google/stackoverflow for an answer and I tried implementing all of them, but there wasn't one that worked for me. Either it's something I'm not seeing, or I'm just not experienced enough to notice. Either way, I would really appreciate any help.
Here are my gradle dependencies:
ext {
// versions for libraries that multiple dependencies
supportLibVersion = '25.1.0'
dagger = '2.7'
butterknife = '8.4.0'
pocketknife = '3.2.1'
}
dependencies {
// Support Libraries
compile "com.android.support:appcompat-v7:${supportLibVersion}"
compile "com.android.support:design:${supportLibVersion}"
compile "com.android.support:support-v4:${supportLibVersion}"
compile "com.android.support:cardview-v7:${supportLibVersion}"
compile "com.android.support:recyclerview-v7:${supportLibVersion}"
//recyclerview from brian wernick
compile 'com.devbrackets.android:recyclerext:2.0.1'
Here is the MainActivity:
public class MainActivity extends BaseActivity implements BottomNavigationView.OnNavigationItemSelectedListener, ViewPager.OnPageChangeListener {
#Inject
EventBus bus;
#BindView(R.id.bottomNavigation)
BottomNavigationView bottomNavigation;
#BindView(R.id.viewpager)
ViewPager viewPager;
private SwipeFragmentPagerAdapter adapter;
#Override
protected int getLayoutResourceId() {
return R.layout.activity_main;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Injector.get().inject(this);
PocketKnife.restoreInstanceState(this, savedInstanceState);
bottomNavigation.setOnNavigationItemSelectedListener(this);
adapter = new SwipeFragmentPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(this);
bus.postSticky(new ViewPagerEvent(adapter.getItem(0).getClass()));
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
int position;
if (item.getItemId() == R.id.menu_item_explore) {
position = 1;
} else if (item.getItemId() == R.id.menu_item_my_goals) {
position = 2;
} else if (item.getItemId() == R.id.menu_item_profile) {
position = 3;
} else {
position = 0;
}
viewPager.setCurrentItem(position, false);
return true;
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//required empty method
}
#Override
public void onPageSelected(int position) {
MenuItem menuItem = bottomNavigation.getMenu().getItem(position);
if (menuItem != null) {
menuItem.setChecked(true);
bus.postSticky(new ViewPagerEvent(adapter.getItem(position).getClass()));
}
}
#Override
public void onPageScrollStateChanged(int state) {
//required empty method
}
}
Here is my adapter:
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.view.ViewGroup;
import com.devbrackets.android.recyclerext.adapter.RecyclerListAdapter;
import com.devbrackets.android.recyclerext.adapter.viewholder.ClickableViewHolder;
import agency.rain.android.simple.things.model.ExploreData;
import agency.rain.android.simple.things.ui.activity.ClickActivity;
import agency.rain.android.simple.things.ui.activity.adapter.viewholder.ExploreViewHolder;
public class ExploreAdapter extends RecyclerListAdapter<ExploreViewHolder, ExploreData> implements ClickableViewHolder.OnClickListener {
private Context context;
public ExploreAdapter(Context context) {
this.context = context;
}
#Override
public ExploreViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return ExploreViewHolder.newInstance(parent, this);
}
#Override
public void onBindViewHolder(ExploreViewHolder holder, int position) {
final ExploreData data = getItem(position);
if (data == null) {
return;
}
holder.bindData(data);
}
#Override
public void onClick(#NonNull ClickableViewHolder viewHolder) {
final ExploreData data = getItem(viewHolder.getAdapterPosition());
Intent repListIntent = new Intent(context, ClickActivity.class);
context.startActivity(repListIntent);
}
}
This is my ViewHolder:
import android.support.annotation.NonNull;
import android.support.v7.widget.CardView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.devbrackets.android.recyclerext.adapter.viewholder.ClickableViewHolder;
import agency.rain.android.simple.things.R;
import agency.rain.android.simple.things.model.ExploreData;
import butterknife.BindView;
import butterknife.ButterKnife;
public class ExploreViewHolder extends ClickableViewHolder {
#BindView(R.id.card_view_explore)
CardView cv;
#BindView(R.id.explore_placeholder_text)
TextView ept;
#BindView(R.id.explore_placeholder_image)
ImageView epi;
private ExploreViewHolder(#NonNull View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
public static ExploreViewHolder newInstance(ViewGroup parent, ClickableViewHolder.OnClickListener listener) {
final ExploreViewHolder viewHolder = new ExploreViewHolder(
LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_explore, parent, false));
viewHolder.setOnClickListener(listener);
return viewHolder;
}
public void bindData(ExploreData data) {
ept.setText(data.getExploreText());
epi.setImageResource(data.getExploreImage());
}
}
This is my Data object:
import java.io.Serializable;
public class ExploreData implements Serializable {
private String exploreText;
private int exploreImage;
public int getExploreImage() {
return exploreImage;
}
public String getExploreText() {
return exploreText;
}
}
This is the Fragment that should be showing the CardView:
public class ExploreFragment extends BaseFragment implements AdapterView.OnItemClickListener {
#BindView(R.id.explore_recycler_view)
RecyclerView exploreRecyclerView;
private Unbinder unbinder;
private ExploreAdapter exploreAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_explore, container, false);
Injector.get().inject(this);
unbinder = ButterKnife.bind(this, view);
PocketKnife.bindArguments(this);
final LinearLayoutManager exploreLayoutManager = new LinearLayoutManager(getActivity());
exploreRecyclerView.setLayoutManager(exploreLayoutManager);
exploreAdapter = new ExploreAdapter(getActivity());
exploreRecyclerView.setAdapter(exploreAdapter);
return view;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onDestroy() {
super.onDestroy();
if (unbinder != null) {
unbinder.unbind();
}
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_explore, menu);
}
#Override
protected int getTitleResourceId() {
return R.string.explore_title_text;
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
}
The Fragment 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="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/explore_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
</LinearLayout>
And last but not least, the list_item xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view_explore"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="4dp"
android:clickable="true"
card_view:cardBackgroundColor="#android:color/white"
android:background="?android:attr/selectableItemBackground"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/explore_placeholder_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/drop_the_pounds"
android:textColor="#android:color/black"
android:textAllCaps="true" />
<ImageView
android:id="#+id/explore_placeholder_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/challengeimage"
android:layout_marginRight="65dp"
android:layout_marginEnd="65dp" />
</RelativeLayout>
</android.support.v7.widget.CardView>

change text size in view pager fragment according seek bar in activity

In my activity (Please see image), I have seek bar and view pager ( have 3 pages).
I want so that, when seek bar in activity change, the text of the fragment size also varies.
How can I do it?
I try it with interface but it not run.
Mainactivity
package com.creativei.viewpagerloop;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
public class MainActivity extends ActionBarActivity {
private static final String LOG_TAG = "ViewPagerLoop";
public static final String[] content = new String[] {
"Hello Welcome to ViewPager Loop Example. This is first view. Swipe right → for second view, swipe left � for last view.",
"Awesome, now you are on second view. Swipe right → again to go to last view.",
"Finally made it to last view, swipe right → again to go to first view." };
Interface inter;
public MainActivity(Interface inter) {
this.inter = inter;
}
private SeekBar seekBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
seekBar = (SeekBar) findViewById(R.id.seekBar1);
ViewPager pager = (ViewPager) findViewById(R.id.pager);
TextView counter = (TextView) findViewById(R.id.counter);
seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
inter.seekBarChange(progress);
}
public void onStartTrackingTouch(SeekBar seekBar) {
}
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
SimpleViewPagerAdapter adapter = new SimpleViewPagerAdapter(
getSupportFragmentManager(), pager, content, counter);
pager.setAdapter(adapter);
pager.setOnPageChangeListener(adapter);
pager.setCurrentItem(1, false);
}
public static class SimpleFragment extends Fragment implements Interface {
private TextView textView;
public SimpleFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
String content = getArguments().getString("content");
textView = (TextView) rootView.findViewById(R.id.content);
textView.setText(content);
return rootView;
}
#Override
public void seekBarChange(int id) {
// TODO Auto-generated method stub
textView.setTextSize(id);
}
}
public static class SimpleViewPagerAdapter extends
FragmentStatePagerAdapter implements OnPageChangeListener {
private String[] content;
private ViewPager pager;
private TextView counter;
public SimpleViewPagerAdapter(FragmentManager fm, ViewPager pager,
String[] content, TextView counter) {
super(fm);
this.pager = pager;
this.content = content;
this.counter = counter;
}
#Override
public Fragment getItem(int position) {
SimpleFragment fragment = new SimpleFragment();
Bundle bundle = new Bundle();
int index = position;
bundle.putString("content", content[index]);
fragment.setArguments(bundle);
return fragment;
}
#Override
public int getCount() {
return content.length;
}
#Override
public void onPageSelected(int position) {
}
private String makeCounterText(int pageNo) {
return "Page " + pageNo + " of " + content.length;
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
}
}
Interface
package com.creativei.viewpagerloop;
public interface Interface {
public void seekBarChange(int id);
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.creativei.viewpagerloop.MainActivity"
tools:ignore="MergeRootFrame" >
<SeekBar
android:id="#+id/seekBar1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/counter"
android:layout_below="#+id/seekBar1" />
<TextView
android:id="#+id/counter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:gravity="center_horizontal" />
</RelativeLayout>
fragment_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.creativei.viewpagerloop.SimpleFragment" >
<TextView
android:id="#+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
You can get reference from this example http://sampleprogramz.com/android/seekbar.php

Add view at end and start of view pager dynamically

Initially my ViewPager takes list and set view accordingly. But if the end of ViewPager or start of ViewPager is reached I want to add more view to ViewPager and set positions accordingly, how can I accomplish this by writing an efficient code?
This is my Adapter
#Override
public Object instantiateItem(ViewGroup container, int position) {
// Declare Variables
TouchImageView image;
ImageEntity entity=list.get(position);
final TextView text;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.viewpager_item, container,false);
// Locate the TextViews in viewpager_item.xml
image = (TouchImageView) itemView.findViewById(R.id.imageView1);
View progress=itemView.findViewById(R.id.progress);
text=(TextView) itemView.findViewById(R.id.text);
text.setVisibility(View.INVISIBLE);
text.setText(entity.message);
makeTextViewResizable(text, 1, "View more", true);
// Capture position and set to the TextViews
image.setImageURI(Uri.parse(Constants.FLDR_IMG+entity.localImageName));
ContextCommons.loadMainImage(context, entity, progress, image);
// Add viewpager_item.xml to ViewPager
container.addView(itemView);
return itemView;
}`
This is custom ViewPager
public class CustomViewPager extends ViewPager{
float mStartDragX;
float x = 0;
OnSwipeOutListener mOnSwipeOutListener;
static final String TAG="CustomViewPager";
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setOnSwipeOutListener(OnSwipeOutListener listener) {
mOnSwipeOutListener = listener;
}
private void onSwipeOutAtStart() {
if (mOnSwipeOutListener!=null) {
mOnSwipeOutListener.onSwipeOutAtStart();
}
}
private void onSwipeOutAtEnd() {
if (mOnSwipeOutListener!=null) {
mOnSwipeOutListener.onSwipeOutAtEnd();
}
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch(ev.getAction() & MotionEventCompat.ACTION_MASK){
case MotionEvent.ACTION_DOWN:
mStartDragX = ev.getX();
break;
}
return super.onInterceptTouchEvent(ev);
}
#Override
public boolean onTouchEvent(MotionEvent ev){
if(getCurrentItem()==0 || getCurrentItem()==getAdapter().getCount()-1){
final int action = ev.getAction();
float x = ev.getX();
switch(action & MotionEventCompat.ACTION_MASK){
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
if (getCurrentItem()==0 && x>mStartDragX) {
/here i want to update ArrayList from start which is supplied to view adapter/
ImageActivity.loadStart();
}
if (getCurrentItem()==getAdapter().getCount()-1 && x<mStartDragX){
//here i want to update Arraylist from bottom which is supplied to view adapter
ImageActivity.loadEnd();
}
break;
}
}else{
mStartDragX=0;
}
return super.onTouchEvent(ev);
}
public interface OnSwipeOutListener {
void onSwipeOutAtStart();
void onSwipeOutAtEnd();
}
}
So I need to update list which is supplied to ViewPager to add dynamic view when ViewPager reaches the end or start.
I am adding view like this which I think is a wrong approach
public static void loadStart(){
ArrayList<ImageEntity> image = null;
try {
ContextCommons.loadImages(context, Constants.DIRECTION_TOP, list.get(0).id);
image= SelectQueries.getTopLocalImagesOnId(context, list.get(0).id, Constants.DIRECTION_TOP);
list.addAll(0,image);
} catch (Exception e) {
e.printStackTrace();
}
viewPager.getAdapter().notifyDataSetChanged();
viewPager.setCurrentItem(image.size()-1);
}
I have made some editis to Googles viewPager example to keep it simple,
by clicking the button on fragment you can easily increase the pages to View Pager.
This is a demo I showed here how to notify anychanges as you wish to increase pages. you will have to make your own custom Adapter and list of pages to keep pages and it's position in check...
I am sorry, I would not be witting entire code :(
Make a fragment with following xml and code...
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_blank_fragment" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button" />
</LinearLayout>
and it's code is
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
/**
* A simple {#link Fragment} subclass.
*/
public class MyFragment extends Fragment {
private Button button;
private TextView textView;
private static AddPage test;
public MyFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View layout = inflater.inflate(R.layout.fragment_my, container, false);
button = (Button) layout.findViewById(R.id.button);
return layout;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
test.addAnotherPage();
}
});
}
public void setAddPage(AddPage addPage) {
test = addPage;
}
public interface AddPage {
void addAnotherPage();
}
}
Main Activity xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".AddingPagesTest">
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Activities Code
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
public class AddingPagesTest extends AppCompatActivity {
public static int NUM_PAGES = 2;
private ViewPager mPager;
private PagerAdapter mPagerAdapter;
private MyFragment set;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_adding_pages_test);
mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_adding_pages_test, menu);
return true;
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter implements MyFragment.AddPage {
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
MyFragment myFragment = new MyFragment();
myFragment.setAddPage(this);
return myFragment;
}
#Override
public int getCount() {
return NUM_PAGES;
}
#Override
public void addAnotherPage() {
NUM_PAGES++;
mPagerAdapter.notifyDataSetChanged();
}
}
}

Items in HListView are not clickable using HorizontalListView

What I need is a Horizontal scrollable ListView that serves as a horizontally scrollable menu.
I searched for a solution and came up with the this library.
I am trying to implement it.sephiroth.android.library.widget.AdapterView.OnItemClickListener on it.sephiroth.android.library.widget.HListView object in a DialogFragment.
I can get the list to populate but I can't seem to be able to attach listeners to the item.
I have been trying for 2 days to figure this out, but no game. This feature is still not working. So I turn to the old WWW for salvation..
This is my DialogFragment XML fragment_layout.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="vertical"
android:background="#800000"
android:descendantFocusability="blocksDescendants" >
<it.sephiroth.android.library.widget.HListView
android:id="#+id/hlvPlacesListScrollMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:scrollbars="none"
android:divider="#android:color/transparent"
/>
this is my viewitem.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#800000"
android:clickable="false"
android:focusable="false"
android:orientation="vertical" >
<ImageButton
android:id="#+id/ibScrollMenuImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#800000"
android:clickable="false"
android:focusable="false"
android:scaleType="centerCrop" />
<TextView
android:id="#+id/tvScrollMenuTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false"
android:gravity="center_horizontal"
android:textColor="#f4f4f4" />
</LinearLayout>
This is my main_activity_layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/llDialogFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#34f34f"
android:orientation="vertical"
tools:context=".MainActivity" >
</LinearLayout>
Pretty basic.
My MainActicity is :
package com.example.hscrollviewtest;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.Menu;
public class MainActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
LifeStatsDialogFragment menuFragment = new LifeStatsDialogFragment();
ft.add(R.id.llDialogFragment, menuFragment).commit();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
the Dialogfrgment .java :
package com.example.hscrollviewtest;
import it.sephiroth.android.library.widget.AdapterView;
import it.sephiroth.android.library.widget.AdapterView.OnItemClickListener;
import it.sephiroth.android.library.widget.HListView;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class LifeStatsDialogFragment extends DialogFragment implements
OnItemClickListener {
private HListView scroll;
private View rootView;
private HorizontalScrollMenuAdapter mAdapter;
final String[] IMAGE_TITLE = new String[] { "Home", "Work", "School",
"Sport" };
final int[] MENU_IMAGES = new int[] { R.drawable.ic_circle_home,
R.drawable.ic_circle_work, R.drawable.ic_circle_school,
R.drawable.ic_circle_gym };
public LifeStatsDialogFragment newInstance() {
return new LifeStatsDialogFragment();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
rootView = inflater.inflate(R.layout.fragment_layout, container, false);
mAdapter = new HorizontalScrollMenuAdapter(getActivity(),
R.layout.fragment_layout, R.id.tvScrollMenuTitle, IMAGE_TITLE,
MENU_IMAGES);
scroll = (HListView) rootView
.findViewById(R.id.hlvPlacesListScrollMenu);
scroll.setAdapter(mAdapter);
scroll.invalidate();
scroll.setOnItemClickListener(this);
for (int i = 0; i < scroll.getAdapter().getCount(); i++) {
Log.i(this.getClass().getSimpleName(), "first item in scroll : "
+ scroll.getChildAt(i) + "and its clickable?? "
+ scroll.getAdapter().getItemViewType(i) + "\n");
}
Log.i(this.getClass().getSimpleName(),
"The number of children for HlistView is: "
+ scroll.getParent().toString());
return rootView;
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
}
}
and this is the adapter(which works when I use it in the HorizontalVariableListViewDemo):
package com.example.hscrollviewtest;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.TextView;
public class HorizontalScrollMenuAdapter extends ArrayAdapter<String>{
private String[] mButtonText;
private int[] mIconId;
private final String TAG = this.getClass().getSimpleName();
//Constructor
public HorizontalScrollMenuAdapter(Context context, int resource,
int textViewResourceId, String[] menuItemName, int[] menuItemImage) {
super(context, resource, textViewResourceId, menuItemName);
// TODO Auto-generated constructor stub
mButtonText = menuItemName;
mIconId = menuItemImage;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return mIconId.length;
}
#Override
public String getItem(int position) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater mInflater = (LayoutInflater) parent.getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.viewitem, null);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.tvScrollMenuTitle);
holder.icon=(ImageButton) convertView.findViewById(R.id.ibScrollMenuImage);
//holder.icon.setBackgroundResource(android.R.color.transparent);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.name.setText(mButtonText[position]);
holder.icon.setImageResource(mIconId[position]);
holder.icon.setTag(mIconId[position]);
Log.d(TAG,"returned view to fragment");
return convertView;
}
static class ViewHolder{
TextView name;
ImageButton icon;
}
}
I hope one of you can see my blindspot.
Thaks
Probably you are implementing the wrong OnItemClickListener.
Try to use
public class LifeStatsDialogFragment extends DialogFragment implements
it.sephiroth.android.library.widget.AdapterView.OnItemClickListener {
//...
}
I would try 2 things:
Put the fragment in the xml layout in the first place, and avoid add in the onCreate.
What happens in the onItemClick? - its currently empty. Try using an independent onItemClickListener:
list.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(getActivity(), "clicked", Toast.LENGTH_SHORT);
}
});

Categories

Resources