I'm migrating from ListView to RecyclerView, but after entering some data in SQLite, my list is not updated using notifyDataSetChanged (); so I always have to call the setAdapter () method;
I have simplified my code to post here. can anyone help me fix the notifyDataSetChanged (); to work in my code please?
RecyclerViewAdapter
public class RecyclerViewAdapter extends RecyclerView.Adapter<ViewHolder> {
private List<Model> model;
private Context context;
public RecyclerViewAdapter(Context context, List<Model> model) {
this.context = context;
this.model = new ArrayList<>(model);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_layout, parent, false);
return new ViewHolder(context, view, model);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final Model model = model.get(position);
holder.bind(model);
}
#Override
public int getItemCount() {
return model.size();
} }
ViewHolder
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private List<Model> model = new ArrayList<>();
private Context context;
private TextView textViewGroup;
private TextView textViewName;
public ViewHolder(Context context, View itemView, List<Model> model) {
super(itemView);
this.model = model;
this.context = context;
itemView.setOnClickListener(this);
textViewGroup = (TextView) itemView.findViewById(R.id.textViewGroup);
textViewName = (TextView) itemView.findViewById(R.id.textViewName);
}
public void bind(Model model) {
textViewGroup.setText(model.getGroup());
textViewName.setText(model.getName());
}
}
#Override
public void onClick(View view) {
Model model = this.model.get(getAdapterPosition());
Intent intent = new Intent(this.context, ShowGroup.class);
intent.putExtra("DATA", model);
intent.putExtra("POSITION", getAdapterPosition());
((Activity) this.context).startActivityForResult(intent, 7);
Log.i(">>", "_IDHOLDER: " + model.getId());
Log.i(">>", "_POSITION: " + getAdapterPosition());
Log.i(">>", ".");
} }
Model
public class Model implements Serializable {
public static final String TABLE = "GROUP_NAME";
public static final String ID = "_ID";
public static final String GROUP = "GROUP";
public static final String NAME = "NAME";
private long id;
private String group;
private String name;
public Model() {
setId(0);
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
} }
Repository
public class Repository {
private SQLiteDatabase db;
public Repository(SQLiteDatabase db) {
this.db = db;
}
private ContentValues fillModelValues(Model model) {
ContentValues values = new ContentValues();
values.put(Model.GROUP, model.getGroup());
values.put(Model.NAME, model.getName());
return values;
}
public void insert(Model model) {
ContentValues values = fillModelValues(model);
db.insertOrThrow(Model.TABLE, null, values);
}
public List<Model> consDataBase(Context context) {
List<Model> listModel = new ArrayList<>();
Cursor cursor = db.query(Model.TABLE, null, null, null, null, null, null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
do {
Model model = new Model();
model.setId(cursor.getLong(cursor.getColumnIndex(Model.ID)));
model.setGroup(cursor.getString(cursor.getColumnIndex(Model.GROUP)));
model.setName(cursor.getString(cursor.getColumnIndex(Model.NAME)));
listModel.add(model);
} while (cursor.moveToNext());
}
cursor.close();
return listModel;
} }
MainActivity
public class MainActivity extends AppCompatActivity {
private List<Model> listModel;
private LinearLayoutManager layoutManager;
private RecyclerView recyclerView;
private RecyclerViewAdapter recyclerViewAdapter;
private FloatingActionButton fab;
private DataBase dataBase;
private SQLiteDatabase db;
private Repository repository;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
layoutManager = new LinearLayoutManager(this);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(layoutManager);
fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivityForResult(new Intent(MainActivity.this, AddGroup.class), 4);
}
});
try {
dataBase = new DataBase(this);
db = dataBase.getWritableDatabase();
repository = new Repository(db);
listModel = repository.consDataBase(context);
recyclerViewAdapter = new RecyclerViewAdapter(context, listModel);
recyclerView.setAdapter(recyclerViewAdapter);
recyclerView.setHasFixedSize(true);
} catch (SQLException e) {
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (db != null) {
db.close();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 4) {
listModel = repository.consDataBase(context);
recyclerViewAdapter = new RecyclerViewAdapter(context, listModel);
recyclerView.setAdapter(recyclerViewAdapter);
}
} }
AddGroup
public class AddGroup extends AppCompatActivity {
private EditText editTextGroup;
private EditText editTextName;
private DataBase dataBase;
private SQLiteDatabase db;
private Repository repository;
private Model model;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_group);
editTextGroup = (EditText) findViewById(R.id.editTextGroup);
editTextName = (EditText) findViewById(R.id.editTextName);
try {
dataBase = new DataBase(this);
db = dataBase.getWritableDatabase();
repository = new Repository(db);
model = new Model();
} catch (SQLException e) {
}
}
private void saveModel() {
try {
model.setGroup(editTextGroup.getText().toString().trim());
model.setName(editTextName.getText().toString().trim());
if (model.getId() == 0) {
repository.insert(model);
}
} catch (Exception e) {
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (db != null) {
db.close();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_add_group, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_save) {
saveModel();
}
return super.onOptionsItemSelected(item);
} }
it's working now
RecyclerViewAdapter
public class RecyclerViewAdapter extends RecyclerView.Adapter<ViewHolder> {
private List<Model> model;
private Context context;
public RecyclerViewAdapter(Context context, List<Model> model) {
this.context = context;
this.model = new ArrayList<>(model);
}
...
public void notify(List<Model> list) {
if (model != null) {
model.clear();
model.addAll(list);
} else {
model = list;
}
notifyDataSetChanged();
}
}
Then in onActivityResult
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 4) {
listModel = repository.consDataBase(this);
recyclerViewAdapter.notify(listModel);
}
}
thank you :)
In order to have your code working you need to change Adapter constructor implementation as follows:
public RecyclerViewAdapter(Context context, List<Model> model) {
this.context = context;
this.model = model;
}
Then in onActivityResult do like this:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 4) {
listModel.clear();
listModel.addAll(repository.consDataBase(context));
recyclerViewAdapter.notifyDataSetChanged();
}
}
Simply put:
RecyclerViewAdapter.notyfyDataSetChanged();
Related
I have a requirement where I need to plan inside subset of data. For example, I have a stock of steel beams of certain grade. While planning I need to fit the available beams into stock only if they match the profile.
How do I do this with constraint streams. Any example would be appreciated.
I don't seem to get the hang around constraint streams.
I need to fit the ProjectMembers into StockMembers only if the profile matches.
Planning entity
#PlanningEntity
public class ProjectMember
extends AbstractPersistable
implements Labeled {
private int requiredLength; // in mm
private String profile;
public String getProfile() {
return profile;
}
public void setProfile(String profile) {
this.profile = profile;
}
private StockMember stockMember;
ProjectMember() {
}
public ProjectMember(long id, int requiredLength) {
super(id);
this.requiredLength = requiredLength;
}
public int getRequiredLength() {
return requiredLength;
}
public void setRequiredLength(int requiredLength) {
this.requiredLength = requiredLength;
}
#PlanningVariable
public StockMember getStockMember() {
return stockMember;
}
public void setStockMember(StockMember stockMember) {
this.stockMember = stockMember;
}
#Override
public String getLabel() {
return "Project Member " + id;
}
}
public class StockMember
extends AbstractPersistable
implements Labeled {
private int length; // in mm
private String profile;
private int cost; // in dollars
StockMember() {
}
public StockMember(long id, int length, int cost) {
super(id);
this.length = length;
this.cost = cost;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public int getCost() {
return cost;
}
public void setCost(int cost) {
this.cost = cost;
}
public void setProfile(String profile) {
this.profile = profile;
}
public String getProfile() {
return this.profile;
}
#Override
#JsonIgnore
public String getLabel() {
return "Stock Member " + id;
}
}
Planning solution
#PlanningSolution
public class NestMembers extends AbstractPersistable {
private List<StockMember> stockMemberList;
private List<ProjectMember> projectMemberList;
private HardSoftScore score;
NestMembers() {
}
public NestMembers(long id, List<StockMember> stockMemberList,
List<ProjectMember> projectMemberList) {
super(id);
this.stockMemberList = stockMemberList;
this.projectMemberList = projectMemberList;
}
#ValueRangeProvider
#ProblemFactCollectionProperty
public List<StockMember> getStockMemberList() {
return stockMemberList;
}
public void setStockMemberList(List<StockMember> computerList) {
this.stockMemberList = computerList;
}
#PlanningEntityCollectionProperty
public List<ProjectMember> getProjectMemberList() {
return projectMemberList;
}
public void setProjectMemberList(List<ProjectMember> projectMemberList)
{
this.projectMemberList = projectMemberList;
}
#PlanningScore
public HardSoftScore getScore() {
return score;
}
public void setScore(HardSoftScore score) {
this.score = score;
}
Constraint Provider
public class NestingConstraintProvider implements ConstraintProvider {
#Override
public Constraint[] defineConstraints(ConstraintFactory
constraintFactory) {
return new Constraint[]{
matchProfile(constraintFactory),
requiredLengthTotal(constraintFactory),
memberCost(constraintFactory)
};
}
Constraint requiredLengthTotal(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(ProjectMember.class)
.groupBy(ProjectMember::getStockMember,
sum(ProjectMember::getRequiredLength))
.filter((stockMember, requiredLength) -> requiredLength >
stockMember.getLength())
.penalize(HardSoftScore.ONE_HARD,
(stockMember, requiredLength) -> requiredLength -
stockMember.getLength())
.asConstraint("requiredLength");
}
Constraint matchProfile(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(ProjectMember.class)
.join(StockMember.class).
filter((projectMember, stockMember) ->
!projectMember.getProfile().equals(stockMember.getProfile()))
.penalize(HardSoftScore.ONE_HARD)
.asConstraint("requiredProfileMatch");
}
//
Constraint memberCost(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(StockMember.class)
.ifExists(ProjectMember.class, equal(Function.identity(),
ProjectMember::getStockMember))
.penalize(HardSoftScore.ONE_SOFT, StockMember::getCost)
.asConstraint("cost");
}
(https://i.stack.imgur.com/t5GM3.jpg)
RecyclerView in side a recyclerView.
The result is loading but not in the particular category. how to show results in a particular category? Can anyone have a solution? ??
public class CategoryAdapter extends RecyclerView.Adapter<CategoryAdapter.ViewHolder> {
Context context;
List<String> list;
ArrayList<StoryModel> storyModels;
StoryAdapter adapter;
DatabaseReference reference;
public CategoryAdapter(Context context, List<String> list) {
this.context = context;
this.list = list;
}
#NonNull
#Override
public CategoryAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.category_item,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull CategoryAdapter.ViewHolder holder, #SuppressLint("RecyclerView") int position) {
holder.categoryTextView.setText(list.get(position));
storyModels = new ArrayList<>();
adapter = new StoryAdapter(context,storyModels);
holder.categoryRelativeLayout.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false));
holder.categoryRelativeLayout.setAdapter(adapter);
reference = FirebaseDatabase.getInstance().getReference().child("Stories").child(list.get(position));
reference.addListenerForSingleValueEvent(new ValueEventListener() {
#SuppressLint("NotifyDataSetChanged")
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()){
StoryModel model = dataSnapshot.getValue(StoryModel.class);
storyModels.add(model);
}
adapter.notifyDataSetChanged();
holder.categoryRelativeLayout.setVisibility(View.VISIBLE);
holder.loadingCategoryStories.setVisibility(View.GONE);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
#Override
public int getItemCount() {
return list.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView categoryTextView;
RecyclerView categoryRelativeLayout;
ProgressBar loadingCategoryStories;
public ViewHolder(#NonNull View itemView) {
super(itemView);
categoryTextView = itemView.findViewById(R.id.categoryTextView);
categoryRelativeLayout = itemView.findViewById(R.id.categoryRelativeLayout);
loadingCategoryStories = itemView.findViewById(R.id.loadingCategoryStories);
}
}
}
public class StoryAdapter extends RecyclerView.Adapter<StoryAdapter.ViewHolder> {
Context context;
ArrayList<StoryModel> data;
public StoryAdapter(Context context, ArrayList<StoryModel> data) {
this.context = context;
this.data = data;
}
#NonNull
#Override
public StoryAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.story_item_view,parent,false);
return new StoryAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull StoryAdapter.ViewHolder holder, int position) {
StoryModel storyModel = data.get(position);
Picasso.get().load(storyModel.getImage())
.placeholder(R.drawable.ic_launcher_background).into(holder.imageStoryItem);
holder.storyItemTitle.setText(storyModel.getTittle());
holder.storyItemAuthor.setText(storyModel.getAuthor());
holder.storyItemTitle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(context, ReadingActivity.class);
i.putExtra("author",storyModel.getAuthor());
i.putExtra("title",storyModel.getTittle());
i.putExtra("image",storyModel.getImage());
i.putExtra("story",storyModel.getStory());
i.putExtra("date",storyModel.getDate());
i.putExtra("key",storyModel.getStoryKey());
ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation((Activity) context,holder.imageStoryItem, ViewCompat.getTransitionName(holder.imageStoryItem));
context.startActivity(i,optionsCompat.toBundle());
}
});
holder.imageStoryItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(context, ReadingActivity.class);
i.putExtra("author",storyModel.getAuthor());
i.putExtra("title",storyModel.getTittle());
i.putExtra("image",storyModel.getImage());
i.putExtra("story",storyModel.getStory());
i.putExtra("date",storyModel.getDate());
i.putExtra("key",storyModel.getStoryKey());
ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation((Activity) context,holder.imageStoryItem, ViewCompat.getTransitionName(holder.imageStoryItem));
context.startActivity(i,optionsCompat.toBundle());
}
});
}
#Override
public int getItemCount() {
return data.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView imageStoryItem;
TextView storyItemTitle,storyItemAuthor;
public ViewHolder(#NonNull View itemView) {
super(itemView);
storyItemTitle = itemView.findViewById(R.id.storyItemTitle);
imageStoryItem = itemView.findViewById(R.id.imageStoryItem);
storyItemAuthor = itemView.findViewById(R.id.storyItemAuthor);
}
}
}
I add “Employee” to the SQLite database. When adding an employee to the database, the user must fill in the fields that relate to the employee, for example, first name, last name, salary, etc. The employee has several attributes such as "skill" and "department" of these attributes the employee may have several, so when the user fills in all the fields with attributes he is invited to add another field, for example, the field "skill" to add another "skill", such a field " skill "you can add as much as you want and I implemented it with RecyclerView. But the problem is this: when the user wants to add another "skill" field, an empty EditText appears and the user fills this field with data, but I don’t know how to save this line, because when you click add skill an empty line is transferred to the adapter, then the user fills this line, but how to save this line to the list that contains the adapter I can not figure out
please watch a gif
This is Adapter class
public class AdapterAddSkill extends RecyclerView.Adapter<AdapterAddSkill.MyViewHolderAddEmployee> {
private ArrayList<String> skillsList;
private Context context;
public AdapterAddSkill(ArrayList<String> skillsList, Context context) {
this.skillsList = skillsList;
this.context = context;
}
#NonNull
#Override
public MyViewHolderAddEmployee onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_skill, parent, false);
return new MyViewHolderAddEmployee(view);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolderAddEmployee holder, final int position) {
holder.closeCard.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
skillsList.remove(position);
notifyDataSetChanged();
}
});
}
#Override
public int getItemCount() {
return skillsList.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
public static class MyViewHolderAddEmployee extends RecyclerView.ViewHolder {
private ImageButton closeCard;
private EditText skillEditText;
public MyViewHolderAddEmployee(#NonNull View itemView) {
super(itemView);
closeCard = itemView.findViewById(R.id.deleteSkillCard);
skillEditText = itemView.findViewById(R.id.skillText);
}
}
}
Here is the activity in which the user fills in the data about the employee and adds it to the database
public class AddEmploy extends AppCompatActivity {
private EditText nameEditText, lastNameEditText, employeeIdEditText,
salaryEditText, departmentEditText, skillEditText;
private ArrayList<String> skillsList = new ArrayList<>();
private ArrayList<String> departmentsList = new ArrayList<>();
private AdapterAddSkill adapterAddSkill;
private RecyclerView skillRecyclerView;
private AdapterAddDepartment adapterAddDepartment;
private RecyclerView departmentRecyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_employ);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
nameEditText = findViewById(R.id.name);
lastNameEditText = findViewById(R.id.lastName);
employeeIdEditText = findViewById(R.id.employeeId);
salaryEditText = findViewById(R.id.salary);
departmentEditText = findViewById(R.id.department);
skillEditText = findViewById(R.id.skill);
skillRecyclerView = findViewById(R.id.rv_skill);
departmentRecyclerView = findViewById(R.id.rv_department);
adapterAddSkill = new AdapterAddSkill(skillsList, this);
adapterAddDepartment = new AdapterAddDepartment(departmentsList, this);
skillRecyclerView.setLayoutManager(new LinearLayoutManager(this));
departmentRecyclerView.setLayoutManager(new LinearLayoutManager(this));
skillRecyclerView.setAdapter(adapterAddSkill);
departmentRecyclerView.setAdapter(adapterAddDepartment);
}
public void onClickBtn(View view) {
switch (view.getId()) {
case R.id.addDepartmentText:
departmentsList.add("");
adapterAddDepartment.notifyDataSetChanged();
break;
case R.id.addSkillText:
skillsList.add("");
adapterAddSkill.notifyDataSetChanged();
break;
case R.id.saveEmployee_info:
addEmployToDatabase();
addDepartmentToDatabase();
addSkillToDatabase();
}
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
finish();
}
return super.onOptionsItemSelected(item);
}
private void addEmployToDatabase() {
String employeeId = employeeIdEditText.getText().toString();
String name = nameEditText.getText().toString();
String lastName = lastNameEditText.getText().toString();
String salary = salaryEditText.getText().toString();
MyQuery.addEmployee(new Employ(employeeId, name, lastName, salary));
}
private void addSkillToDatabase() {
String employeeId = employeeIdEditText.getText().toString();
String skill = skillEditText.getText().toString();
MyQuery.addSkill(new Skill(employeeId, skill));
for (int i = 0; i < skillsList.size(); i++) {
MyQuery.addSkill(new Skill(employeeIdEditText.getText().toString()
, skillsList.get(i)));
}
}
private void addDepartmentToDatabase() {
String department = departmentEditText.getText().toString();
String employeeId = employeeIdEditText.getText().toString();
MyQuery.addDepartment(new Department(employeeId, department));
for (int i = 0; i < departmentsList.size(); i++) {
MyQuery.addDepartment(new Department(employeeIdEditText.getText().toString(),
departmentsList.get(i)));
}
}
private void showAllEmployees() {
List<Employ> employs = MyQuery.getAllEmployees();
for (int i = 0; i < employs.size(); i++) {
Log.i(".......Employees", employs.get(i).toString());
}
}
private void showAllSkills() {
List<Skill> skills = MyQuery.getAllSkills();
for (int i = 0; i < skills.size(); i++) {
Log.i("......Skills", skills.get(i).toString());
}
}
private void showAllDepartments() {
List<Department> departments = MyQuery.getAllDepartments();
for (int i = 0; i < departments.size(); i++) {
Log.i(".........Departments", departments.get(i).toString());
}
}
}
public class AdapterAddSkill extends RecyclerView.Adapter<AdapterAddSkill.MyViewHolderAddEmployee> {
private ArrayList<String> skillsList;
public AdapterAddSkill(ArrayList<String> skillsList) {
this.skillsList = skillsList;
}
#NonNull
#Override
public MyViewHolderAddEmployee onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_skill, parent, false);
MyViewHolderAddEmployee vh = new MyViewHolderAddEmployee(view, new MyCustomEditTextListener());
return vh;
}
#Override
public void onBindViewHolder(#NonNull final MyViewHolderAddEmployee holder, final int position) {
holder.myCustomEditTextListener.updatePosition(position);
holder.skillEditText.setText(skillsList.get(position));
holder.closeCard.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
skillsList.remove(position);
notifyItemRemoved(position);
}
});
}
#Override
public int getItemCount() {
return skillsList.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
public static class MyViewHolderAddEmployee extends RecyclerView.ViewHolder {
private ImageButton closeCard;
private EditText skillEditText;
private MyCustomEditTextListener myCustomEditTextListener;
public MyViewHolderAddEmployee(#NonNull View itemView, MyCustomEditTextListener myCustomEditTextListener) {
super(itemView);
closeCard = itemView.findViewById(R.id.deleteSkillCard);
skillEditText = itemView.findViewById(R.id.skillText);
skillEditText.addTextChangedListener(myCustomEditTextListener);
this.myCustomEditTextListener = myCustomEditTextListener;
}
}
private class MyCustomEditTextListener implements TextWatcher {
private int position;
public void updatePosition(int position) {
this.position = position;
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
skillsList.set(position, s.toString());
}
#Override
public void afterTextChanged(Editable s) {
}
}
}
Entities and Pojos must have a usable public constructor. You can have an empty constructor or a constructor whose parameters match the fields (by name and type)
Am integrating room into my existing project. While annotating a POJO, which implements Parcelable, with #Entity tag and making necessary changes, am getting this error. I already have an empty constructor in it. Any help would be appreciated.
#Entity(tableName = "Departments")
public class Department implements Parcelable {
#PrimaryKey(autoGenerate = true)
private Integer primaryId;
private Integer id;
private String departmentName;
private String logoUrl;
#Embedded
private ArrayList<Template> templateList;
public Department() {
}
protected Department(Parcel in) {
this.primaryId = (Integer) in.readSerializable();
this.departmentName = in.readString();
this.logoUrl = in.readString();
this.id = (Integer) in.readSerializable();
this.templateList = in.createTypedArrayList(Template.CREATOR);
}
public static final Creator<Department> CREATOR = new Creator<Department>() {
#Override
public Department createFromParcel(Parcel in) {
return new Department(in);
}
#Override
public Department[] newArray(int size) {
return new Department[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeSerializable(primaryId);
dest.writeString(departmentName);
dest.writeString(logoUrl);
dest.writeSerializable(id);
dest.writeTypedList(templateList);
}
public Integer getPrimaryId() {
return primaryId;
}
public void setPrimaryId(Integer primaryId) {
this.primaryId = primaryId;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLogoUrl() {
return logoUrl;
}
public void setLogoUrl(String logoUrl) {
this.logoUrl = logoUrl;
}
public String getDepartmentName() {
return departmentName;
}
public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
}
public ArrayList<Template> getTemplateList() {
return templateList;
}
public void setTemplateList(ArrayList<Template> templateList) {
this.templateList = templateList;
}
}
#Entity(tableName = "Templates")
public class Template implements Parcelable {
#PrimaryKey(autoGenerate = true)
private Integer primaryId;
private Integer id;
private String code;
private String description;
private Integer departmentId;
#Embedded
private ArrayList<Issue> issueList;
public Template() {
}
private Template(Parcel in) {
this.primaryId = (Integer) in.readSerializable();
this.code = in.readString();
this.description = in.readString();
this.id = (Integer) in.readSerializable();
this.departmentId = (Integer) in.readSerializable();
this.issueList = in.createTypedArrayList(Issue.CREATOR);
}
public static final Creator<Template> CREATOR = new Creator<Template>() {
#Override
public Template createFromParcel(Parcel in) {
return new Template(in);
}
#Override
public Template[] newArray(int size) {
return new Template[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeSerializable(primaryId);
dest.writeString(code);
dest.writeString(description);
dest.writeSerializable(id);
dest.writeSerializable(departmentId);
dest.writeTypedList(issueList);
}
public Integer getPrimaryId() {
return primaryId;
}
public void setPrimaryId(Integer primaryId) {
this.primaryId = primaryId;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public ArrayList<Issue> getIssueList() {
return issueList;
}
public void setIssueList(ArrayList<Issue> issueList) {
this.issueList = issueList;
}
public Integer getDepartmentId() {
return departmentId;
}
public void setDepartmentId(Integer departmentId) {
this.departmentId = departmentId;
}
}
#Entity(tableName = "Issues")
public class Issue implements Parcelable {
#PrimaryKey(autoGenerate = true)
private Integer primaryId;
private Integer id;
private String code;
private String description;
private Integer parentIssue;
public Issue() {
}
protected Issue(Parcel in) {
this.primaryId = (Integer) in.readSerializable();
this.code = in.readString();
this.description = in.readString();
this.id = (Integer) in.readSerializable();
this.parentIssue = (Integer) in.readSerializable();
}
public static final Creator<Issue> CREATOR = new Creator<Issue>() {
#Override
public Issue createFromParcel(Parcel in) {
return new Issue(in);
}
#Override
public Issue[] newArray(int size) {
return new Issue[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeSerializable(primaryId);
dest.writeString(code);
dest.writeString(description);
dest.writeSerializable(id);
dest.writeSerializable(parentIssue);
}
public Integer getPrimaryId() {
return primaryId;
}
public void setPrimaryId(Integer primaryId) {
this.primaryId = primaryId;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getParentIssue() {
return parentIssue;
}
public void setParentIssue(Integer parentIssue) {
this.parentIssue = parentIssue;
}
}
Room assumes your entity class will be having only one constructor. But there is no such limitations, If you have multiple constructor then annotate one of them with
#Ignore
Room will ignore this constructor and compile without any error.
Example
#Entity(tableName = "Departments")
public class Department implements Parcelable {
#PrimaryKey(autoGenerate = true)
private Integer primaryId;
private Integer id;
private String departmentName;
private String logoUrl;
#Embedded
private ArrayList<Template> templateList;
/**Room will ignore this constructor
**/
#Ignore
public Department() {
}
protected Department(Parcel in) {
this.primaryId = (Integer) in.readSerializable();
this.departmentName = in.readString();
this.logoUrl = in.readString();
this.id = (Integer) in.readSerializable();
this.templateList = in.createTypedArrayList(Template.CREATOR);
}
}
I'm not sure why you are getting your specific constructor error. That said your code will error from embedding the ArrayList. #Embedded is not meant to be used this way. #Embedded allows you to flatten your POJO structure when storing it. Nested POJO properties will appear as if they had been properties on the parent POJO. Using Embedded on a List is the same as asking it to flatten the properties of the ArrayList object and store them, not flatten the list items and store them.
The appropriate measure is to transition into a foreign key, primary key relationship. An alternative solution is to create a new POJO that contains your list of items (ie Templates, with an 's'). This would contain an ArrayList of Template objects. You would then define a converter that converts the POJO to a json/comma seperated list, and stores it in a single column that by default would be called "templates". Here is a link to this approach :
Android room persistent library - TypeConverter error of error: Cannot figure out how to save field to database"
Hope this helps.
I have created a Xamarin.Forms app in Visual Studio that connects to an Azure SQL Database via an Azure Mobile App. So far everything is working fine - I can do CRUD operations on the database from my Xamarin App.
However I have not yet been able to perform an inner join query on two or more tables.
I have created one such query in a View on the Database, and it works ok on the server, but my problem is that I do not know how to connect to this View from the Xamarin.Forms app.
I would really appreciate any help :-)
Thank you!
XAMARIN.FORMS SERVICE CLASS FOR A GENERIC AZURE TABLE:
public class service<T> : serviceBase<T> where T : irlm.azure.models.modelBase
{
public async Task<ObservableCollection<T>> get()
{
var items = await table.ToEnumerableAsync();
return new ObservableCollection<T>(items);
}
public async Task<T> update(T item)
{
if (item.Id == null)
await table.InsertAsync(item);
else
await table.UpdateAsync(item);
return item;
}
public async Task delete(T item)
{
await table.DeleteAsync(item);
}
}
public abstract class serviceBase<T>
{
MobileServiceClient dc;
public IMobileServiceTable<T> table;
public serviceBase()
{
dc = new MobileServiceClient(irlm.constants.appUrl);
table = dc.GetTable<T>();
}
}
XAMARIN.FORMS MODEL EXAMPLE
public abstract class modelBase
{
public string Id { get; set; }
}
public class golfClub : modelBase
{
public string name { get; set; }
}
public class golfCourse : modelBase
{
public string idClub { get; set; }
public string name { get; set; }
}
XAMARIN.FORMS VIEWMODEL:
public class viewModel<T> : INotifyPropertyChanged
{
private ObservableCollection<T> _items = new ObservableCollection<T>();
public ObservableCollection<T> items
{
get { return _items; }
set
{
_items = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
CONTENT PAGE:
irlm.azure.viewModels.viewModel<irlm.azure.models.golfClub> golfClubs = new azure.viewModels.viewModel<azure.models.golfClub>();
irlm.azure.services.service<irlm.azure.models.golfClub> dc = new azure.services.service<azure.models.golfClub>();
ListView list;
Entry txt = new Entry();
private async void BtnAdd_Clicked(object sender, EventArgs e)
{
var golfCourse = await dc.update(new irlm.azure.models.golfClub { name = txt.Text });
golfClubs.items.Add(golfCourse);
}
private async void BtnUpdate_Clicked(object sender, EventArgs e)
{
var index = golfClubs.items.IndexOf(list.SelectedItem as irlm.azure.models.golfClub);
var item = (irlm.azure.models.golfClub)list.SelectedItem;
item.name = txt.Text;
await dc.update(item);
golfClubs.items[index] = item;
}
private async void BtnRemove_Clicked(object sender, EventArgs e)
{
var item = (irlm.azure.models.golfClub)list.SelectedItem;
await dc.delete(item);
golfClubs.items.Remove((irlm.azure.models.golfClub)list.SelectedItem);
txt.Text = "";
}