Why instantiateItem doesn't call and ViewPager doesn't work? - java

I try to make simple application with sliding images. I use this article http://www.androidbegin.com/tutorial/android-viewpager-gallery-images-and-texts-tutorial/.
This is my xml with viewpager:
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<android.support.v4.view.ViewPager
android:id="#+id/pages"
android:layout_height="match_parent"
android:layout_width="match_parent">
</android.support.v4.view.ViewPager>
</LinearLayout>
this is my xml with image:
item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="#+id/image"
android:layout_gravity="center"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="#drawable/ic_launcher" />
</RelativeLayout>
this is my adapter:
ViewerPagerAdapter.java
public class ViewerPagerAdapter extends PagerAdapter {
private Context mContext;
private ArrayList<CueModel> mArray;
private LayoutInflater mInflater;
private ImageView mImage;
public ViewerPagerAdapter(Context _context){
mContext = _context;
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void setArray(ArrayList<Bitmap> arr){
mArray = arr;
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
View itemView = mInflater.inflate(R.layout.item, container, false);
mImage = (ImageView)itemView.findViewById(R.id.image);
mImage.setImageBitmap(mArray.get(position));
container.addView(itemView);
return itemView;
}
#Override
public int getCount() {
return mArray.size();
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View)object);
}
#Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0.equals(arg1);
}
this is my activity:
OneActivity.java
(mArrays full of image)
public class OneActivity extends Activity {
ArrayList<Bitmap> mArrays;
ViewerPagerAdapter mAdapter;
ViewPager mPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main.xml);
mPager = (ViewPager) findViewById(R.id.pages);
mAdapter = new ViewerPagerAdapter(OneActivity.this);
mAdapter.setArrays(mArrays);
mPager.setAdapter(mAdapter);
}
}
I don't understand what I did wrong. instantiateItem doesn't call.
PS.Difference between my app and
article I have a few activity(and my arraylist initialized by items)
Thank you

#instantiateItem() is called whenever the ViewPager needs a new View. Initially, it'll call #instantiateItem() twice for the View in the center and view to the right if the adapter's getCount() > 0. That's why in your #setArray() method you need to call #notifyDataSetChanged() every time you change the array. You also need to call it every time you add or remove items from the list. If your array is empty in #onCreate(), then #getCount() == 0 so the ViewPager thinks it's empty and won't bother.

I know this is very old post but I am answering this becoz someone would get benefited. I got the same issue - instantiateItem () was not getting called.
After trying so many thing I manage to finally found the mistake I did in my code and it was a silly one I forgot to set adapter to viewpager:
viewPager.setAdapter(adapter)

For modern versions (2020+) where the error message is
Binary XML file line #(lineNumber): Error inflating class android.viewpager.widget.ViewPager
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
you might want to update
android.support.v4.view.ViewPager to
androidx.viewpager.widget.ViewPager

In my case, the size of the list was zero. Therefore, this method was not calling. When the list was not empty, it worked properly.

Related

OnItemClickListener not getting invoked on Button inside GridView

I am trying to create a GridView that contains some buttons. The buttons are getting populated but the OnItemClickListener() is not getting invoked when a Button inside the GridView is clicked.
Activty Class Code
gridView = (GridView) findViewById(R.id.gridview);
gridView.setAdapter(new ButtonAdapter(getApplicationContext(),answer));
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
flipper.showNext();
}
});
Custom Button Adapter
public class ButtonAdapter extends BaseAdapter{
private Context context;
private int[] numbers = new int[100];
private String[] answer;
public ButtonAdapter (Context context,String[] answer){
this.context = context;
this.answer = answer;
for(int i=0;i<100;i++){
numbers[i] = i+1;
}
}
#Override
public int getCount() {
return numbers.length;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
View gridView;
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if(view == null) {
gridView = new View(context);
gridView = inflater.inflate(R.layout.adapter, null);
} else {
gridView = (View) view;
}
Button button = (Button) gridView.findViewById(R.id.adapter_button);
button.setText(numbers[i]+"");
if(answer[i].equals("null"))
button.setBackgroundColor(context.getResources().getColor(R.color.reset));
else
button.setBackgroundColor(context.getResources().getColor(R.color.optionCheck));
return gridView;
}
}
adapter.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/adapter_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
acitvity_layout.xml
<GridView
android:id="#+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:numColumns="5"
android:columnWidth="50dp"
android:stretchMode="columnWidth"
android:layout_below="#+id/back"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
You need to implement an interface and have your Activity subscribe to the specific button presses via the interface listener. Your ButtonAdapter should implement the onClickListener, but your Activity should implement the interface with your custom methods. The Activity and the Adapter are two different worlds with two different scopes. Go through this post slowly and follow its logic. It should set you in the right direction: How to create interface between Fragment and adapter?
The way an adapter works with a Fragment is virtually the same as it does with an Activity.

How to make card style menu in android

I want to add card style in my app like this
i use in my app mysql database so i need to make like this cards and put my data from database in it now i use ListView with this code
public void listAllItme() {
ListAdapter lA = new listAdapter(listitems);
listView.setAdapter(lA);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent open = new Intent(R_arabic.this, rewaya_show.class);
open.putExtra("name", listitems.get(position).name);
open.putExtra("url", listitems.get(position).url);
open.putExtra("img", listitems.get(position).img);
open.putExtra("num", listitems.get(position).num);
startActivity(open);
}
}
});
}
class listAdapter extends BaseAdapter {
ArrayList<listitem_gib> lista = new ArrayList<listitem_gib>();
public listAdapter(ArrayList<listitem_gib> lista) {
this.lista = lista;
}
#Override
public int getCount() {
return lista.size();
}
#Override
public Object getItem(int position) {
return lista.get(position).name;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = getLayoutInflater();
View view = layoutInflater.inflate(R.layout.row_item_gib, null);
TextView name = (TextView) view.findViewById(R.id.textView_gib);
ImageView img = (ImageView) view.findViewById(R.id.imageView_gib);
TextView num = (TextView) view.findViewById(R.id.textView_gib2);
TextView size = (TextView) view.findViewById(R.id.textView_gib3);
name.setText(lista.get(position).name);
num.setText(lista.get(position).num);
size.setText(lista.get(position).size);
Picasso.with(R_arabic.this).load("http://grassyhat.com/android/image/" + lista.get(position).img).into(img);
return view;
}
}
first i want to know how i can make like this card style
second how i can use this code with card menu not listview
sorry im new in android and sorry for my bad english
What do you mean by card menu? because the example in the image is a recyclerview with a cardview item, you can achieve this by doing something like this
This will be your activity
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView)findViewById(R.id.recyclerView);
//Just your list of objects, in your case the list that comes from the db
List<Items> itemsList = new ArrayList<>();
CardAdapter adapter = new CardAdapter(this, itemsList);
//RecyclerView needs a layout manager in order to display data so here we create one
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
//Here we set the layout manager and the adapter to the listview
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
}
Inside the layout file you just have to place the recyclerview like this
<RelativeLayout
android:id="#+id/activity_main"
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"
tools:context="jsondh.myapplication.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
Then your adapter will be something like this
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.CardViewHolder> {
private List<Items> itemsList;
private Activity activity;
public CardAdapter(Activity activity, List<Items> items){
this.activity = activity;
this.itemsList = items;
}
#Override
public CardViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = activity.getLayoutInflater().inflate(R.layout.cardview_layout, parent, false);
return new CardViewHolder(itemView);
}
#Override
public void onBindViewHolder(CardViewHolder holder, int position) {
//Here you bind your views with the data from each object from the list
}
#Override
public int getItemCount() {
return itemsList.size();
}
public class CardViewHolder extends RecyclerView.ViewHolder {
public ImageView bookImage;
public TextView bookLabel01, bookLabel02;
public CardViewHolder(View itemView) {
super(itemView);
bookImage = (ImageView)itemView.findViewById(R.id.image);
bookLabel01 = (TextView)itemView.findViewById(R.id.label01);
bookLabel02 = (TextView)itemView.findViewById(R.id.label02);
}
}
And the last one will be the layout from each item on the list, like this
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp">
<android.support.v7.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardElevation="15dp"
app:cardBackgroundColor="#3369Ed">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/image"
android:layout_width="150dp"
android:layout_height="130dp"/>
<TextView
android:id="#+id/label01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Label"
android:layout_gravity="right"
android:padding="5dp"
android:textColor="#ffffff"/>
<TextView
android:id="#+id/label02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LongerLabel"
android:layout_gravity="right"
android:padding="5dp"
android:textColor="#ffffff"/>
</LinearLayout>
</android.support.v7.widget.CardView>
You also have to add this to your gradle file:
compile 'com.android.support:recyclerview-v7:25.0.0'
compile 'com.android.support:cardview-v7:25.0.0'
Hope it helps!
It's pretty simple. You will have to use a RecyclerView with GridLayoutManager and add a cardView to it.
Then, use an Adapter and ViewHolder to feed the data.
I suggest you to check this out:
https://developer.android.com/training/material/lists-cards.html

Multiple RecyclerViews in same layout: Click listener for one gets triggered for all recyclerViews

I have two recyclerViews (say A and B) in the same layout that have an adapter which for both the recyclerViews look like this:
public class ChapterListAdapter extends RecyclerView.Adapter<ChapterListAdapter.ChapterListViewHolder>{
private final ArrayList<ChapterObj> mChapterListObj;
private final Context mContext;
public ChapterListAdapter(ArrayList<ChapterObj> chapterObj, Context c) {
mChapterListObj = chapterObj;
mContext = c;
}
#Override
public ChapterListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.chapter_list_item, parent, false);
ChapterListViewHolder vh = new ChapterListViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(ChapterListViewHolder holder, int position) {
holder.chapterNumber.setText(mChapterListObj.get(position).getChapterNumber());
}
#Override
public int getItemCount() {
return mChapterListObj.size();
}
public class ChapterListViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnTouchListener {
private TextView chapterNumber;
public ChapterListViewHolder(View itemView) {
super(itemView);
chapterNumber = (TextView) itemView.findViewById(R.id.chapter_number);
itemView.setOnClickListener(this);
itemView.setOnTouchListener(this);
}
#Override
public void onClick(View v) {
Log.d("hello", "hello");
}
}
}
}
Both A and B have click listeners. Independently, both work fine. But when both are in the same layout, whenever I click on an item of 'A', the click listener of 'B' gets triggered.
If you need to see more code, tell me which file you want to see, I'll add their code too.
Edit: The xml layout file in which I've used them together looks like this:
<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"
tools:context=".VerseActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/chapter_list_menu"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
xmlns:android="http://schemas.android.com/apk/res/android"
>
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.RecyclerView
android:id="#+id/verse_list_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentTop="true"
xmlns:android="http://schemas.android.com/apk/res/android"
>
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
You can do same thing with Sectioned recycler view. which will even load faster and let you display as many sectioned as you want. (removes hurdle of 2-3 recyclerview in same page or view)
If you want to create your own you can check this - https://gist.github.com/gabrielemariotti/4c189fb1124df4556058
or you can find many libraries for that also.

How can I setText to a TextView in every single row of my ListView

Hi guys I am new to Android and also to stackoverflow, Greetings and thanks for the help.
I have 2 Xml files for the same activity. One that contains a ListView and the second as my custom layout for an ArrayAdapter that populates a ListView which is also included on my first layout:
<include android:id="#+id/lv" layout="#layout/lv_row" />
ListView Custom Layout (lv_row.xml):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:id="#+id/icon"
android:src="#drawable/ic_launcher"/>
<TextView
android:layout_toRightOf="#+id/icon"
android:layout_width="fill_parent"
android:layout_height="38dp"
android:textSize="30sp"
android:id="#+id/label"/>
<TextView
android:layout_toRightOf="#+id/icon"
android:layout_below="#+id/label"
android:layout_width="fill_parent"
android:layout_height="12dp"
android:gravity="bottom"
android:id="#+id/label2"
android:textSize="12sp"/>
</RelativeLayout>
This is my adapter:
final ArrayAdapter<String> Array = new ArrayAdapter<String>(this,R.layout.lv_row,R.id.label,myList);
I save strings one by one into "myList" and display them on my ListView, what I want to do is to enumerate the elements on my list view by using idNum.setText(iterating_variable.toString())... but it won't work because idNum always get the value that was set on the XML file.
This is the code I use to link the second XML with my Java code
lv = (RelativeLayout) findViewById(R.id.lv);
idNum = (TextView) lv.findViewById(R.id.label2);
Thanks again for your help.
create custom Adapter and setText() in getView() method of adapter
like
class CustomAdapter extends BaseAdapter {
private ArrayList<String> mList;
private LayoutInflater mInflater;
public CustomAdapter(ArrayList<String> list) {
mList = list;
mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return mList.size() ;
}
#Override
public Object getItem(int position) {
return mList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null)
convertView = mInflater.inflate(R.layout.lv_row, null);
((TextView) convertView.findViewById(R.id.label2)).setText(mList.get(position));
return convertView;
}
}
and set on ListView

New to Android - Fragments

New to android programming. For the past 3 days I've been going through tutorials and feel like I get the major parts of it. Every time I try to run the following code, android causes it to force quit before even opening up. I've gotten other more simpler fragments to work with little effort, but this is confusing me. There is no error being printed at all, probably because it shuts down immediately. Any help would be much aprreciated.
EDIT: Using the debugger I was able to get an
"InflateException: Binary XML file #9: Error inflating class fragment.
It stops after the follwing code:
lv = (ListView) view.findViewById(R.id.lvMain);
Frag_MainList.java
public class Frag_MainList extends Fragment implements OnItemClickListener, OnItemLongClickListener{
ListView lv;
ImageView ivAddNote;
Communicator communicator;
Adapter_SQL database = new Adapter_SQL(getActivity());
ArrayList<Element> list;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag_mainlist, container, false);
lv = (ListView) view.findViewById(R.id.lvMain);
database.open();
list = database.getChildrenLess();
database.close();
Adapter_List adapter = new Adapter_List(getActivity(), list);
lv.setAdapter(adapter);
lv.setOnItemClickListener(this);
lv.setOnItemLongClickListener(this);
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
#Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
communicator.SendID(pos);
return true;
}
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
database.open();
database.switchComplete(list.get(pos).id);
database.close();
}
public void setCommunicator(Communicator communicator){
this.communicator = communicator;
}
public interface Communicator{
public void SendID(int index);
}
}
Activity_Main.java
public class Activity_Main extends Activity implements Frag_MainList.Communicator{
Frag_MainList frag1;
Frag_ListChildren frag_children;
FragmentManager manager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
manager = getFragmentManager();
frag1 = (Frag_MainList) manager.findFragmentById(R.id.fMainList);
frag1.setCommunicator(this);
}
#Override
public void SendID(int index) {
frag_children = (Frag_ListChildren) manager.findFragmentById(R.id.fListChildren);
if (frag_children != null && frag_children.isVisible()){
frag_children.displayChildren(index);
}else{
Intent intent = new Intent("com.likwid.wishlist.LISTCHILDREN");
intent.putExtra("id", index);
startActivity(intent);
}
}
}
frag_mainlist.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" >
<ListView
android:id="#+id/lvMain"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
activity_main.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="wrap_content"
android:background="#00BBFF"
android:orientation="horizontal"
android:id="#+id/main_layout" >
<fragment
android:id="#+id/fMainList"
android:name="com.likwid.wishlist.Frag_MainList"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</LinearLayout>
I figured it out. It seems the problem was with the database. getActivity in Frag_MainList would be called before the activity was actually created. Putting getActivity in the the "onActivityCreated" method allowed for getActivity to be properly called and seemed to take away all the problems it was causing. I think the reason it was showing a fragment error is because the fragment was faulty, making inflating in it impossible. Thanks everyone!

Categories