android / architecture-samples Goto Github PK
View Code? Open in Web Editor NEWA collection of samples to discuss and showcase different architectural tools and patterns for Android apps.
License: Apache License 2.0
A collection of samples to discuss and showcase different architectural tools and patterns for Android apps.
License: Apache License 2.0
I read the previous discussion #72 and understand the approach, but most layout logic could be replaced with @BindingAdapter
annotation and people could see their power, one example
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@{stats.status}"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="@{stats.showStatus ? View.VISIBLE : View.GONE}" />
could be replaced with
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@{stats.status}"
android:textAppearance="?android:attr/textAppearanceMedium"
app:visibility_value="@{stats.showStatus}"
and
public class VisibilityBinding {
@BindingAdapter({
"visibility_value"
})
public static void bindVisibility(View view, boolean visible) {
bindVisibility(visible, View.VISIBLE, View.GONE);
}
@BindingAdapter({
"visibility_value",
"visibility_off"
})
public static void bindVisibility(View view, boolean visible, int visibilityOffValue) {
bindVisibility(visible, View.VISIBLE, visibilityOffValue);
}
@BindingAdapter({
"visibility_value",
"visibility_off",
"visibility_on"
})
public static void bindVisibility(View view, boolean visible, int visibilityOffValue, int visibilityOnValue) {
view.setVisibility(visible ? visibilityOnValue : visibilityOffValue);
}
}
could even create binding app:hidden
app:invisible
first one use View.GONE
for false value, second one use View.INVISIBLE
that it's a better naming, and the only logic xml have it's negation mark !
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@{stats.status}"
android:textAppearance="?android:attr/textAppearanceMedium"
app:hidden="@{!stats.showStatus}"
public class VisibilityBinding {
@BindingAdapter({
"hidden"
})
public static void bindHiddenVisibility(View view, boolean hidden) {
view.setVisibility(hidden ? View.GONE : View.VISIBLE);
}
@BindingAdapter({
"invisible"
})
public static void bindInvisibleVisibility(View view, boolean invisible) {
view.setVisibility(hidden ? View.INVISIBLE : View.VISIBLE);
}
}
WDYT guys?
Error:(97, 37) 警告: [unchecked] 方法调用未经过检查: 将接口 View中的方法 showTasks应用到给定的类型
需要: List
找到: List
I was thinking about working on an example of this over the weekend. MVVM + databinding were made for each other and it would be nice if there was an example
This project does not use the Gradle build system. We recommend that you migrate to using the Gradle build system...why
I'm testing the app and getting an arror when adding a task
my phone is galaxy s3
android: 5.0.1
android studio 2.2 preview
gradle: 2.2.alpha
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.architecture.blueprints.todomvpdagger.mock, PID: 8462
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.architecture.blueprints.todomvpdagger.mock/com.example.android.architecture.blueprints.todoapp.addedittask.AddEditTaskActivity}: android.view.InflateException: Binary XML file line #30: Error inflating class EditText
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2702)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2767)
at android.app.ActivityThread.access$900(ActivityThread.java:177)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1449)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5951)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
Caused by: android.view.InflateException: Binary XML file line #30: Error inflating class EditText
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:770)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:821)
at android.view.LayoutInflater.inflate(LayoutInflater.java:511)
at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
at com.example.android.architecture.blueprints.todoapp.addedittask.AddEditTaskFragment.onCreateView(AddEditTaskFragment.java:99)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617)
at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:339)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:601)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1234)
at android.app.Activity.performStart(Activity.java:6329)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2767)
at android.app.ActivityThread.access$900(ActivityThread.java:177)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1449)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5951)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
Caused by: android.content.res.Resources$NotFoundException: File res/drawable-v21/abc_edit_text_material.xml from drawable resource ID #0x7f020015
at android.content.res.Resources.loadDrawableForCookie(Resources.java:3735)
at android.content.res.Resources.loadDrawable(Resources.java:3603)
at android.content.res.TypedArray.getDrawable(TypedArray.java:762)
at android.view.View.<init>(View.java:3957)
at android.widget.TextView.<init>(TextView.java:998)
at android.widget.EditText.<init>(EditText.java:74)
at android.widget.EditText.<init>(EditText.java:70)
at android.support.v7.widget.AppCompatEditText.<init>(AppCompatEditText.java:60)
at android.support.v7.widget.AppCompatEditText.<init>(AppCompatEditText.java:56)
at android.support.v7.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:112)
at android.support.v7.app.AppCompatDelegateImplV7.createView(AppCompatDelegateImplV7.java:980)
at android.support.v7.app.AppCompatDelegateImplV7.onCreateView(AppCompatDelegateImplV7.java:1039)
at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(LayoutInflaterCompatHC.java:44)
at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:181)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:732)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:821)
at android.view.LayoutInflater.inflate(LayoutInflater.java:511)
at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
at com.example.android.architecture.blueprints.todoapp.addedittask.AddEditTaskFragment.onCreateView(AddEditTaskFragment.java:99)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617)
at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:339)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:601)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1234)
at android.app.Activity.performStart(Activity.java:6329)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2767)
at android.app.ActivityThread.access$900(ActivityThread.java:177)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1449)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5951)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
Caused by: org.xmlpull.v1.XmlPullParserException: Binary XML file line #24: <nine-patch> requires a valid 9-patch source image
at android.graphics.drawable.NinePatchDrawable.updateStateFromTypedArray(NinePatchDrawable.java:445)
at android.graphics.draw
Based in todo-mvp, using Loaders and Content Providers.
TaskDetailFragment line 148 should be
if (!mDetailCompleteStatus.isChecked())
processLoadedTasks()
should refresh the local data source, not just the in-memory cache.
Hi all,
I have a question regarding the dagger-mvp-update branch.. I am trying to make a sample for rxjava+retrofit +dagger using the beautiful sample that you guys have provided. I saw for each fragment we have a fragment component and a module for that specific view..I really liked this idea but I was just concerned will this be same when i have 1 activity holding 10 fragment or more.. Also I wanted to ask is there any specific reason for starting the presenter cycle from on resume?
Also a huge thanks to you all for putting your efforts in making this beautiful sample👍
Hi,
thanks for the great android architecture examples.
Please create a sample that uses mvp.
thx
In the todo project we simply have one POJO(Task
) and we already have a bloated model layer here. It's quite common to have dozens of POJOs in a REAL project. And it's easy to imagine how big the repository would grow. Whenever I want to add amend something, like adding a Owner(of a Task), I have to add so many lines of code in each one of the classes in the model layer. No need to mention that we have to write so many hardcoded SQL statements.
Is there a better way to avoid these things?
some espresso tests fail.
android.support.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with content description: is "Navigate up"
In some case, one view need more than one presenter to accomplish business.
So I always change the code like..
View
private FirstPresenter mFirstPresenter;
private SecondPresenter mSecondPresenter;
public void addPresenter(Presenter presenter) {
if (presenter instanceof FirstPresenter ) {
mFirstPresenter = (FirstPresenter) presenter;
}
if (presenter instanceof SecondPresenter ) {
mSecondPresenter = (SecondPresenter) presenter;
}
}
how to import this to android studio?
Sample based on MVP but without fragments.
I wanna submit an un official sample request.
Sample500px
I have made this sample combining dagger2, rxjava, and retrofit2
Please let me know your thoughts :)
Thanks to the community for making this project open source 👍
tested with rxjava-branch
UPDATE:
Should even happen in basic-sample.
The Presenter
is just created and code like this in the activity looks pretty lame although meaningful work happens in the presenter constructor
Proposal:
Introduce a method bind
in the Presenter
.
So, the code in presenter class will be:
class ddEditTaskPresenter implements
AddEditTaskContract.Presenter,
TasksDataSource.GetTaskCallback {
Presenter(...) {
this.blah = checkNotNull(blah);
...
}
bind() {
mAddTaskView.setPresenter(this);
}
}
and the activity will be:
class AddEditTaskActivity {
onCreate(...) {
....
presenter = new AddEditTaskPresenter(....);
//wherever required...
presenter.bind();
}
}
Thoughts?
A layout with multiple fragments per screen would showcase how to keep data fresh between views and send messages between presenters.
Like mentioned in #9 this sample will come after RxJava and Dagger2 sample.
@ErikHellman I suggest to use a BaseFragment for collecting all subscriptions in a CompositeSubscription and unsubscribing in onPause().
Please let me know if I should create a PR to discuss this.
when network api callback, the view may not be able to handle UI updates anymore, how to deal with and how to check?
the view holds the presenter instance, presenter holds view instance, and presenter holds data loader instance. so that when network is slow , and user close activity without data loader calling back,the activity instance will not be freed and collected . if user open and close activity with data loading frequently, in this moment, many activities in memory will not be freed, and the memory use will increase. how to deal with? and what about using SoftReference to view in presenter?
Based on MVP but using Dagger2 for dependency injection.
java.lang.IllegalStateException: View can not be anchored to the the parent CoordinatorLayout
I think it crash in tasks_act.xml,
app:layout_anchor="@id/coordinatorLayout"
will throw this.
I try to change to
app:layout_anchor="@id/contentFrame"
but it doesn't work
Based on MVP, create a sample that uses Clean architecture.
No need to import 14k methods just to do checkNotNull()
, checkArguments()
, Lists.newArrayList()
, Objects.equal()
, and Objects.hashCode()
https://gist.github.com/AfzalivE/6c813c770aea498610f235001ee065ef
I can submit a PR if needed.
In addition to this, maybe there should be a method count column in the readme code metrics.
Method count went from 34398 to 19808.
User should be informed about successful actions. For "delete task" normally it's a good style to add an "undo" button in snackbar.
no examples at mvvm architectures?
Duplicate #53
Based on MVP but using RxJava for asynchronous jobs, event handling and data observation.
todo-mvp:Injection class is missing
Hi guys, I'd like to contribute with a MVC and MVC-Dagger2 architecture sample. It would be something similar to what I used in this project https://github.com/Smart-Studio/device-info/tree/develop. Let me know your thoughts.
Calculation of the statistics in StatisticsPresenter
looks more like a domain logic, not a presentation.
Plus StatisticsPresenter
right now have dependency on TasksFilterType
, which could be avoided.
My suggestion is to create an additional UseCase
: GetStatistics
, which will simplify StatisticsPresenter
, and make it independent from tasks
and data
packages.
I implemented it here, it is required some polishing, but I hope that idea is clear.
in TaskDetailActivity.java
Here will case NPE.
...
public class TaskDetailActivity extends AppCompatActivity {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
...
if (taskDetailFragment == null) {
taskDetailFragment = taskDetailFragment.newInstance(taskId);
...
}
...
try
taskDetailFragment = TaskDetailFragment.newInstance(taskId);
Hey guys, thanks for the awesome repo and the samples!
Not sure if this is nitpicking or not but, even though the databinding
lib offers quite an elaborate set of options to add logic directly into the layout files (example: determining the visibility of an element in statistics_frag.xml
) I think that power should be relinquished to the Presenter since one is in place.
In essence, since the todo-databinding
arch is based on MVP, it's probably more suitable to remove any logic from all layout files and put it in appropriate getters in the respective presenters (or ViewModels as depicted in README.md). Databinding will still be used in the layouts but only to connect to the presenter.
I could work on that goal if this gets a few 👍
Thanks! 😃 ❤️
I'm not sure if this make sense, 'cause the RxJava version is already in progress and both may result in similar codes. Nevertheless, would be interested to see the differences fleshed out.
Based on Flux but using RxJava for asynchronous jobs, event handling and data observation and
using Dagger2 for dependency injection.
Pre and post-minifying.
I have a small question, about relation between Presenters and TaskRepository.
Why all Presenters, but AddEditTaskPresenter
, have link directly to TasksRepository
, instead of TasksDataSource
? Using interface will make code a little bit more decoupled, since interface provides all required methods.
If this behaviour is intended, then, probably, AddEditTaskPresenter
should also have link directly to TasksRepository
.
In AddEditTaskFragment, the logic to decide whether to update task or create a new task is made and presenter method is called accordingly.
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isNewTask()) {
mPresenter.createTask(
mTitle.getText().toString(),
mDescription.getText().toString());
} else {
mPresenter.updateTask(
mTitle.getText().toString(),
mDescription.getText().toString());
}
}
});
Shouldn't the view just pass the user action to presenter and let presenter decide?
As the presenter knows whether its a new task or a task update, this decision can be deferred to presenter and view does not have to store any information related to the task.
Thoughts?
I wanna submit an un-official sample request.
Sample500px
I have made this sample using retrofit2, dagger, rxjava following MVP architecture provided by you guys.
Please let me know your thoughts.
Thanks to community for this project open source. 👍
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.